https://vjudge.net/problem/CodeChef-GERALD07
可以用莫队+带撤销并查集做
错误记录:
1.调试时数组开小了,忘了改大就交了
2.88行和91行少了备份num(后来无意改了固定块大小才发现)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<cmath> 6 #include<cassert> 7 using namespace std; 8 #define fi first 9 #define se second 10 #define mp make_pair 11 #define pb push_back 12 typedef long long ll; 13 typedef unsigned long long ull; 14 typedef pair<int,int> pii; 15 #define N 200000 16 int T,n,m,q; 17 struct Q 18 { 19 int l,r,num; 20 }; 21 pii b[N+100]; 22 int ans[N+100],sz,sz1; 23 int be[N+100]; 24 vector<Q> c[N+100]; 25 26 int fa[N+100],dp[N+100],num; 27 int bx[N*300],bfa[N*300],bdp[N*300],mem; 28 int find(int x) 29 { 30 for(;x!=fa[x];x=fa[x]); 31 return x; 32 } 33 void unionn(int x,int y,int &nn) 34 { 35 x=find(x),y=find(y); 36 if(x==y) return; 37 num--; 38 if(dp[x]<dp[y]) fa[x]=y; 39 else 40 { 41 fa[y]=x; 42 if(dp[x]==dp[y]) dp[x]++; 43 } 44 } 45 void unionn_b(int x,int y,int &nn) 46 { 47 x=find(x),y=find(y); 48 if(x==y) return; 49 nn++;num--; 50 ++mem;bx[mem]=x;bfa[mem]=fa[x];bdp[mem]=dp[x]; 51 ++mem;bx[mem]=y;bfa[mem]=fa[y];bdp[mem]=dp[y]; 52 assert(mem<N*300); 53 if(dp[x]<dp[y]) fa[x]=y; 54 else 55 { 56 fa[y]=x; 57 if(dp[x]==dp[y]) dp[x]++; 58 } 59 } 60 void backn(int &nn) 61 { 62 for(int i=1;i<=nn;i++) 63 { 64 fa[bx[mem]]=bfa[mem];dp[bx[mem]]=bdp[mem];--mem; 65 fa[bx[mem]]=bfa[mem];dp[bx[mem]]=bdp[mem];--mem; 66 } 67 assert(mem==0); 68 nn=0; 69 } 70 71 int main() 72 { 73 int i,j,j2,nn,l,r,tnum; 74 scanf("%d",&T); 75 while(T--) 76 { 77 scanf("%d%d%d",&n,&m,&q);sz=max(1,int(sqrt(double(m)*m/q)));sz1=(m-1)/sz; 78 for(i=0;i<=sz1;i++) c[i].clear(); 79 for(i=1;i<=m;i++) be[i]=(i-1)/sz; 80 num=n; 81 for(i=1;i<=m;i++) scanf("%d%d",&b[i].fi,&b[i].se); 82 for(i=1;i<=n;i++) fa[i]=i; 83 for(i=1;i<=q;i++) 84 { 85 scanf("%d%d",&l,&r); 86 if(be[l]==be[r]) 87 { 88 nn=0;tnum=num; 89 for(j=l;j<=r;j++) unionn_b(b[j].fi,b[j].se,nn); 90 ans[i]=num; 91 backn(nn);num=tnum; 92 } 93 else c[be[l]].pb({l,r,i}); 94 } 95 for(i=0;i<=sz1;i++) 96 { 97 sort(c[i].begin(),c[i].end(),[](auto &a,auto &b){return a.r<b.r;}); 98 l=(i+1)*sz;r=l-1;num=n;mem=0; 99 for(j=1;j<=n;j++) fa[j]=j; 100 for(j=0;j<c[i].size();j++) 101 { 102 while(r<c[i][j].r) ++r,unionn(b[r].fi,b[r].se,nn); 103 tnum=num;nn=0; 104 for(j2=l-1;j2>=c[i][j].l;j2--) unionn_b(b[j2].fi,b[j2].se,nn); 105 ans[c[i][j].num]=num; 106 backn(nn);num=tnum; 107 } 108 } 109 for(i=1;i<=q;i++) printf("%d ",ans[i]); 110 } 111 return 0; 112 }