BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
3514: Codechef MARCH14 GERALD07加强版
Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501
[Submit][Status][Discuss]
Description
N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。
Input
第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
接下来M行,代表图中的每条边。
接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。
Output
K行每行一个整数代表该组询问的联通块个数。
Sample Input
3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
Sample Output
2
1
3
1
1
3
1
HINT
对于100%的数据,1≤N、M、K≤200,000。
2016.2.26提高时限至60s
Source
刚刚去看了CreationAugust的Blog,感觉好伤感,也许我的未来就是这样吧
这道题好神啊
LCT维护动态最小生成树,先将每条边依次加进去,若形成环弹掉最早加进去的边,然后记录early[]数组,表示第i条边弹掉了哪条边,若没有弹出边,early[i]=0
然后每个询问的答案就是用n减掉[l,r]区间内ntr值小于l的边的数量 可以用主席树来维护
注意有自环
early[i]数组记录的边不算的话i就可以贡献一个连通分量了,所以这样做
又调了好长时间,最后发现主席树挂掉了因为以前写顺手了虽然是mid=(l+r)>>1但还是用了m...............RE一片
最后说一下一道题用了多个大数据结构怎么办:
1.可以用namespace
2.宏定义是可以取消的,#undef 名字
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define pa t[x].fa #define lc t[x].ch[0] #define rc t[x].ch[1] const int N=2e5+5; typedef long long ll; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,m,Q,type; struct LCTnode{ int ch[2],fa,rev,w,mx,p; }t[N<<1]; inline int wh(int x){return t[pa].ch[1]==x;} inline int isRoot(int x){return t[pa].ch[0]!=x&&t[pa].ch[1]!=x;} inline void update(int x){ t[x].mx=t[x].w;t[x].p=x; if(t[lc].mx>t[x].mx) t[x].mx=t[lc].mx,t[x].p=t[lc].p; if(t[rc].mx>t[x].mx) t[x].mx=t[rc].mx,t[x].p=t[rc].p; } inline void rever(int x){ t[x].rev^=1; swap(lc,rc); } inline void pushDown(int x){ if(t[x].rev){ rever(lc); rever(rc); t[x].rev=0; } } inline void rotate(int x){ int f=t[x].fa,g=t[f].fa,c=wh(x); if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g; t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f; t[x].ch[c^1]=f;t[f].fa=x; update(f);update(x); } int st[N],top; inline void splay(int x){ top=0;st[++top]=x; for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa; for(int i=top;i>=1;i--) pushDown(st[i]); for(;!isRoot(x);rotate(x)) if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x); } inline void Access(int x){ for(int y=0;x;y=x,x=pa){ splay(x); rc=y; update(x); } } inline void MakeR(int x){ Access(x);splay(x); rever(x); } inline int FindR(int x){ Access(x);splay(x); while(lc) x=lc; return x; } inline void Link(int x,int y){ MakeR(x); t[x].fa=y; } inline void Cut(int x,int y){ MakeR(x);Access(y);splay(y); t[y].ch[0]=t[x].fa=0; update(y);//!!! } inline void Split(int x,int y){ MakeR(x);Access(y);splay(y); } inline int Que(int x,int y){ MakeR(x);Access(y);splay(y); return t[y].p; } struct edge{ int u,v; }e[N]; int early[N]; void Kruskal(){ for(int i=1;i<=m;i++){//printf("kru %d\n",i); int u=e[i].u,v=e[i].v; if(u==v) {early[i]=i;continue;} if(FindR(u)==FindR(v)){ int p=Que(u,v); early[i]=p-n; Cut(e[p-n].u,p);Cut(e[p-n].v,p); } Link(u,i+n);Link(v,i+n); } } #undef lc #undef rc #define lc(x) t[x].l #define rc(x) t[x].r namespace F{ struct Fnode{ int l,r,size; }t[N*30]; int sz=0,root[N]; void ins(int &x,int l,int r,int p){ t[++sz]=t[x]; x=sz; t[x].size++; if(l==r) return; int mid=(l+r)>>1; if(p<=mid) ins(t[x].l,l,mid,p); else ins(t[x].r,mid+1,r,p); } int que(int x,int y,int l,int r,int ql,int qr){//printf("que %d %d %d %d\n",l,r,ql,qr); if(ql<=l&&r<=qr) return t[y].size-t[x].size; else{ int m=(l+r)>>1,ans=0; if(ql<=m) ans+=que(lc(x),lc(y),l,m,ql,qr); if(m<qr) ans+=que(rc(x),rc(y),m+1,r,ql,qr); return ans; } } int l,r,lastans=0; void solve(){ for(int i=1;i<=m;i++) root[i]=root[i-1],ins(root[i],0,m,early[i]); //for(int i=0;i<=m;i++) printf("root %d\n",root[i]); while(Q--){ l=read();r=read(); if(type) l^=lastans,r^=lastans; lastans=n-que(root[l-1],root[r],0,m,0,l-1); printf("%d\n",lastans); } } } int main(){ //freopen("in.txt","r",stdin); n=read();m=read();Q=read();type=read(); for(int i=1;i<=m;i++){ e[i].u=read(),e[i].v=read(); t[i+n].w=t[i+n].mx=m+n-i+1; t[i+n].p=i+n; } Kruskal(); F::solve(); }
Copyright:http://www.cnblogs.com/candy99/