bzoj3237: [Ahoi2013]连通图
上线段树分治
它删除的边的总数不会很大,我们可以维护一条边在那一段时间里面是存在的
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> using namespace std; struct edge{int x,y;}e[410000]; struct trnode { int l,r,lc,rc; vector<int>id; }tr[410000];int trlen; void bt(int l,int r) { int now=++trlen; tr[now].l=l;tr[now].r=r; tr[now].lc=tr[now].rc=-1; if(l<r) { int mid=(l+r)/2; tr[now].lc=trlen+1;bt(l,mid); tr[now].rc=trlen+1;bt(mid+1,r); } } void change(int now,int l,int r,int p) { if(tr[now].l==l&&tr[now].r==r) { tr[now].id.push_back(p); return ; } int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid) change(lc,l,r,p); else if(mid+1<=l)change(rc,l,r,p); else change(lc,l,mid,p),change(rc,mid+1,r,p); } int n,cnt,fa[410000]; int findfa(int x) { if(fa[x]<0)return x; return findfa(fa[x]); } struct Clear { int fx,fy,dx,dy,id; Clear(){} Clear(int FX,int FY,int DX,int DY,int ID){fx=FX,fy=FY,dx=DX,dy=DY,id=ID;} }sta[410000];int top; void merge(int now,int x,int y) { int fx=findfa(x),fy=findfa(y); if(fx!=fy) { cnt++; sta[++top]=Clear(fx,fy,fa[fx],fa[fy],now); if(fa[fx]<fa[fy]) fa[fx]+=fa[fy],fa[fy]=fx; else fa[fy]+=fa[fx],fa[fx]=fy; } } void sprit(int p) { cnt--; fa[sta[p].fx]=sta[p].dx; fa[sta[p].fy]=sta[p].dy; } bool as[410000]; void dfs(int now) { for(int i=0;i<tr[now].id.size();i++) merge(now,e[tr[now].id[i]].x,e[tr[now].id[i]].y); if(cnt==n-1) { for(int i=tr[now].l;i<=tr[now].r;i++)as[i]=true; } else if(tr[now].l==tr[now].r); else { dfs(tr[now].lc); dfs(tr[now].rc); } while(sta[top].id==now) sprit(top--); } int las[410000]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int m,x,y; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d",&e[i].x,&e[i].y); for(int i=1;i<=m;i++)las[i]=1; int Q,S; scanf("%d",&Q); trlen=0;bt(1,Q); for(int q=1;q<=Q;q++) { scanf("%d",&S); for(int i=1;i<=S;i++) { scanf("%d",&x); if(las[x]<=q-1) { change(1,las[x],q-1,x); // printf("%d %d %d\n",x,las[x],q-1); } las[x]=q+1; } } for(int i=1;i<=m;i++) if(las[i]<=Q) { change(1,las[i],Q,i); // printf("%d %d %d\n",i,las[i],Q); } for(int i=1;i<=m;i++)fa[i]=-1; cnt=top=0;dfs(1); for(int i=1;i<=Q;i++) if(as[i])printf("Connected\n"); else printf("Disconnected\n"); return 0; }
pain and happy in the cruel world.