题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效。问有多少种通行证可以使得1和N连通。

思路:和bzoj魔法森林有点像,LCT维护最小生成树。  开始和队友在想维护连通性,而不是维护树,这样好像会很麻烦。

队友yy了一个算法:用线段树模拟并查集维护连通性。(发现和标程有点像?

我的代码:LCT维护最小生成树。

...先给代码,后面补一下题解。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
vector<int>e[];
int n,m,t[],q[],siz[],ans,efree,a[],cnt,l[],r[],u[],v[],f[];
template<class T>
inline void read(T&a){
char c=getchar();
for(a=;(c<''||c>'')&&c!='-';c=getchar());
bool f=;if(c=='-')f=,c=getchar();
for(;c>=''&&c<='';c=getchar())a=a*+c-'';
if(f)a=-a;
}
inline int gf(int x){return x==f[x]?f[x]:gf(f[x]);}
void ins(int k,int nl,int nr,int l,int r,int x){
if(nl==l&&nr==r)return (void)e[k].push_back(x);
int mid=(nl+nr)>>;
if(r<=mid)ins(k<<,nl,mid,l,r,x);
else if(l>mid)ins(k<<|,mid+,nr,l,r,x);
else ins(k<<,nl,mid,l,mid,x),ins(k<<|,mid+,nr,mid+,r,x);
}
void dfs(int k,int l,int r){
vector<int>lastf;
int m=e[k].size(),mid=(l+r)>>;
for(register int i=;i<m;i++){
int x=u[e[k][i]],y=v[e[k][i]];
x=gf(x),y=gf(y);
if(siz[x]>siz[y])swap(x,y);
lastf.push_back(x);f[x]=y;siz[y]+=siz[x];
}
if(gf()==gf(n))ans+=a[r+]-a[l];
else if(l<r)dfs(k<<,l,mid),dfs(k<<|,mid+,r);
m=lastf.size();
for(register int i=m-;i>=;i--)f[lastf[i]]=lastf[i];
lastf.clear();
}
int main(){
read(n),read(m);
for(int i=;i<=n;i++)f[i]=i,siz[i]=;
for(int i=;i<=m;i++){
read(u[i]),read(v[i]),read(l[i]),read(r[i]);
a[++cnt]=l[i];a[++cnt]=r[i]+;
}
sort(a+,a++cnt);cnt=unique(a+,a++cnt)-a-;
for(int i=;i<=m;i++)
ins(,,cnt-,lower_bound(a+,a++cnt,l[i])-a,lower_bound(a+,a++cnt,r[i]+)-a-,i);
dfs(,,cnt-);printf("%d\n",ans);
return ;
}

LCT代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
const int inf=;
struct edge{
int x,y,a,b;
}e[maxn];
bool cmp (edge w,edge v){
return w.b>v.b;
}
void read(int &x){
char c=getchar(); x=;
for(;c>''||c<'';c=getchar());
for(;c<=''&&c>='';c=getchar()) x=(x<<)+(x<<)+c-'';
}
struct LCT
{
int Max[maxn],rev[maxn],ch[maxn][],fa[maxn],stc[maxn],top;
int isroot(int x){
return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
}
int get(int x){
return ch[fa[x]][]==x;
}
void pushdown(int x)
{
if(!rev[x]||!x) return ;
swap(ch[x][],ch[x][]);
if(ch[x][]) rev[ch[x][]]^=;
if(ch[x][]) rev[ch[x][]]^=;
rev[x]=;
}
void pushup(int x)
{
Max[x]=x;
if(ch[x][]&&e[Max[ch[x][]]].a>e[Max[x]].a) Max[x]=Max[ch[x][]];
if(ch[x][]&&e[Max[ch[x][]]].a>e[Max[x]].a) Max[x]=Max[ch[x][]];
}
void rotate(int x)
{
int old=fa[x],fold=fa[old],opt=get(x);
if(!isroot(old)) ch[fold][get(old)]=x;
fa[x]=fold;
ch[old][opt]=ch[x][opt^]; fa[ch[old][opt]]=old;
ch[x][opt^]=old; fa[old]=x;
pushup(old); pushup(x);
}
void splay(int x)
{
int top=; stc[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) stc[++top]=fa[i];
for(int i=top;i;i--) pushdown(stc[i]);
for(int f;!isroot(x);rotate(x)){
if(!isroot(f=fa[x]))
rotate(get(x)==get(f)?f:x);
}
}
void access(int x)
{
int rson=;
for(;x;rson=x,x=fa[x]){
splay(x);
ch[x][]=rson;
pushup(x);
}
}
int find(int x){ access(x); splay(x); while(ch[x][]) x=ch[x][]; return x;}
int query(int x,int y) { make_root(y); access(x); splay(x); return Max[x]; }
void make_root(int x) { access(x); splay(x); rev[x]^=; }
void link(int x,int y) { make_root(x); fa[x]=y; splay(x); }
void cut(int x,int y) { make_root(x); access(y); splay(y); fa[x]=ch[y][]=; }
}S;
pair<int,int>fcy[maxn]; int tot;
int main()
{
int N,M,i,ans=;
read(N); read(M);
for(i=;i<=M;i++){
read(e[i].x); read(e[i].y);
read(e[i].a); read(e[i].b);
}
sort(e+,e+M+,cmp);
for(i=;i<=M;i++){
if(S.find(M+e[i].x)!=S.find(M+e[i].y)) {
S.link(i,M+e[i].x);
S.link(i,M+e[i].y);
}
else{
int tmp=S.query(M+e[i].x,M+e[i].y);
if(e[tmp].a>e[i].a) {
S.cut(tmp,M+e[tmp].x); S.cut(tmp,M+e[tmp].y);
S.link(i,M+e[i].x); S.link(i,M+e[i].y);
}
}
if(S.find(M+)==S.find(M+N)){
int tmp=S.query(M+,M+N);
if(e[tmp].a<=e[i].b){
tot++;
fcy[tot].first=e[tmp].a; fcy[tot].second=e[i].b;
}
}
}
sort(fcy+,fcy+tot+);
for(i=;i<=tot;i++){
int j=i,Mx=fcy[i].second;
while(j+<=tot&&fcy[j+].first<=Mx) {
j++; Mx=max(Mx,fcy[j].second);
}
ans+=Mx-fcy[i].first+;
i=j;
}
printf("%d\n",ans);
return ;
}

2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)的更多相关文章

  1. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  2. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  3. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  4. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  5. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  6. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  7. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  8. 2019牛客暑期多校训练营(第二场)J-Subarray(思维)

    >传送门< 前言 这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维 ...

  9. 2019牛客暑期多校训练营(第一场)-A (单调栈)

    题目链接:https://ac.nowcoder.com/acm/contest/881/A 题意:给定两个长度均为n的数组a和b,求最大的p使得(a1,ap)和(b1,bp)等价,等价的定义为其任意 ...

随机推荐

  1. 管道通信——FIFO的代码实现

    一.用到的函数 umask         linux中的 umask 函数主要用于:在创建新文件或目录时 屏蔽掉新文件或目录不应有的访问允许权限.         文件的访问允许权限共有9种,分别是 ...

  2. 实现一个特殊的栈,要求push,poll , getMin方法时间复杂度都是O(N)

    借助两个栈来实现 public class GetMinStack { private Stack<Integer> stackData; private Stack<Integer ...

  3. idea(2018.3.5)破解

    第一步:下载idea,https://www.jetbrains.com/idea/download/#section=windows,双击进行安装 第二步:下载破解的jar包:链接:https:// ...

  4. C语言函数调用

    1.backtrace一些内存检测工具如Valgrind,调试工具如GDB,可以查看程序运行时函数调用的堆栈信息,有时候在分析程序时要获得堆栈信息,借助于backtrace是很有帮助的,其原型如下: ...

  5. vs2017专业版和企业版的密钥

    Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH

  6. Redis 获取和设置密码

    1.config get reuqirepass //获取当前密码 2.config set requirepass "password"//设置当前密码,双引号里面为密码

  7. WPF 在MVVM模式下弹出子窗体的方式

    主要是通过一个WindowManager管理类,在window后台代码中通过WindowManager注册需要弹出的窗体类型,在ViewModel通过WindowManager的Show方法,显示出来 ...

  8. springmvc集成shiro后,session、request是否发生变化

    1. 疑问 我们在项目中使用了spring mvc作为MVC框架,shiro作为权限控制框架,在使用过程中慢慢地产生了下面几个疑惑,本篇文章将会带着疑问慢慢地解析shiro源码,从而解开心里面的那点小 ...

  9. 1.ZooKeeper ACL权限控制

    参考:https://blog.csdn.net/liuxiao723846/article/details/79391650 ZK 类似文件系统,Client 可以在上面创建节点.更新节点.删除节点 ...

  10. redis设计与实现(一)简单动态字符串

    redis是C语言实现的,但redis中的字符串并没有直接用C语言中的字符串表示,而是自己构建了一种简单的动态字符串类型(SDS). 在redis里面,C字符串只用作字面量,用在一些不会修改的地方,e ...