Chef and Graph Queries CodeChef - GERALD07

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\n",ans[i]);
110     }
111     return 0;
112 }

 

posted @ 2018-07-17 11:23  hehe_54321  阅读(715)  评论(0编辑  收藏  举报
AmazingCounters.com