BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)

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

Sample Output

2
1
3
1

解题思路:

LCT维护连通图,维护最早被删除的边。

像HH的项链那样搞就好了。

只不过是主席树。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 const int N=1000000;
  5 class PST{
  6     #define lll tr[spc].ls
  7     #define rrr tr[spc].rs
  8     public:
  9         void update(int l,int r,int &spc,int lst,int pos,int v)
 10         {
 11             spc=++siz;
 12             tr[spc]=tr[lst];
 13             tr[spc].val+=v;
 14             if(l==r)
 15                 return ;
 16             int mid=(l+r)>>1;
 17             if(pos<=mid)
 18                 update(l,mid,tr[spc].ls,tr[lst].ls,pos,v);
 19             else
 20                 update(mid+1,r,tr[spc].rs,tr[lst].rs,pos,v);
 21             return ;
 22         }
 23         int query(int l,int r,int ll,int rr,int spc)
 24         {
 25             if(!spc)
 26                 return 0;
 27             if(l>rr||ll>r)
 28                 return 0;
 29             if(ll<=l&&r<=rr)
 30                 return tr[spc].val;
 31             int mid=(l+r)>>1;
 32             return query(l,mid,ll,rr,lll)+query(mid+1,r,ll,rr,rrr);
 33         }
 34         void fit(int array_size)
 35         {
 36             size=array_size;
 37             return ;
 38         }
 39         int Query(int l,int r)
 40         {
 41             int ans=0;
 42             ans=query(1,size,l,r,root[r]);
 43             return ans;
 44         }
 45         void ops(int pos)
 46         {
 47             root[pos]=root[pos-1];
 48             return ;
 49         }
 50         void Add(int i,int pos,int v)
 51         {
 52             update(1,size,root[i],root[i],pos,v);
 53             return ;
 54         }
 55     private:
 56         struct trnt{
 57             int ls;
 58             int rs;
 59             int val;
 60         }tr[N*10];
 61         int root[N];
 62         int siz;
 63         int size;
 64     #undef lll
 65     #undef rrr
 66 }P;
 67 class LCT{
 68     #define lll tr[spc].ch[0]
 69     #define rrr tr[spc].ch[1]
 70     #define ls ch[0]
 71     #define rs ch[1]
 72     public:
 73         bool whc(int spc)
 74         {
 75             return tr[tr[spc].fa].rs==spc;
 76         }
 77         void pushup(int spc)
 78         {
 79             tr[spc].mv=tr[spc].sl;
 80             if(lll)
 81                 tr[spc].mv=std::min(tr[spc].mv,tr[lll].mv);
 82             if(rrr)
 83                 tr[spc].mv=std::min(tr[spc].mv,tr[rrr].mv);
 84             return ;
 85         }
 86         void trr(int spc)
 87         {
 88             if(!spc)
 89                 return ;
 90             std::swap(lll,rrr);
 91             tr[spc].lzt^=1;
 92             return ;
 93         }
 94         void pushdown(int spc)
 95         {
 96             if(tr[spc].lzt)
 97             {
 98                 trr(lll);
 99                 trr(rrr);
100                 tr[spc].lzt=0;
101             }
102             return ;
103         }
104         void recal(int spc)
105         {
106             if(!tr[spc].anc)
107                 recal(tr[spc].fa);
108             pushdown(spc);
109             return ;
110         }
111         void rotate(int spc)
112         {
113             int f=tr[spc].fa;
114             bool k=whc(spc);
115             tr[f].ch[k]=tr[spc].ch[!k];
116             tr[spc].ch[!k]=f;
117             if(tr[f].anc)
118             {
119                 tr[f].anc=0;
120                 tr[spc].anc=1;
121             }else
122                 tr[tr[f].fa].ch[whc(f)]=spc;
123             tr[spc].fa=tr[f].fa;
124             tr[f].fa=spc;
125             tr[tr[f].ch[k]].fa=f;
126             pushup(f);
127             pushup(spc);
128             return ;
129         }
130         void splay(int spc)
131         {
132             recal(spc);
133             while(!tr[spc].anc)
134             {
135                 int f=tr[spc].fa;
136                 if(tr[f].anc)
137                 {
138                     rotate(spc);
139                     return ;
140                 }
141                 if(whc(spc)^whc(f))
142                     rotate(spc);
143                 else
144                     rotate(f);
145                 rotate(spc);
146             }
147             return ;
148         }
149         void access(int spc)
150         {
151             int lst=0;
152             while(spc)
153             {
154                 splay(spc);
155                 tr[rrr].anc=1;
156                 tr[lst].anc=0;
157                 rrr=lst;
158                 pushup(spc);
159                 lst=spc;
160                 spc=tr[spc].fa;
161             }
162             return ;
163         }
164         void Mtr(int spc)
165         {
166             access(spc);
167             splay(spc);
168             trr(spc);
169             return ;
170         }
171         void split(int x,int y)
172         {
173             Mtr(x);
174             access(y);
175             splay(y);
176             return ;
177         }
178         void link(int x,int y)
179         {
180             Mtr(x);
181             tr[x].fa=y;
182             return ;
183         }
184         bool check(int x,int y)
185         {
186             Mtr(x);
187             access(y);
188             splay(y);
189             pushdown(y);
190             while(tr[y].ls)
191             {
192                 y=tr[y].ls;
193                 pushdown(y);
194             }
195             return x==y;
196         }
197         int minplace(int x,int y)
198         {
199             split(x,y);
200             return tr[y].mv;
201         }
202         void cut(int x,int y)
203         {
204             split(x,y);
205             tr[y].ls=0;
206             tr[x].fa=0;
207             tr[x].anc=true;
208             pushup(y);
209             return ;
210         }
211         void fit(int size1,int size2)
212         {
213             siz=size1+size2;
214             for(int i=1;i<=size1;i++)
215                 tr[i].sl=0x3f3f3f3f;
216             for(int i=1;i<=size2;i++)
217                 tr[i+size1].sl=i;
218             for(int i=1;i<=siz;i++)
219             {
220                 tr[i].anc=true;
221                 pushup(i);
222             }
223             return ;
224         }
225     private:
226         struct int_2{
227             int v;
228             int p;
229         };
230         struct trnt{
231             int ch[2];
232             int fa;
233             int lzt;
234             bool anc;
235             int sl;
236             int mv;
237         }tr[N];
238         int siz;
239     #undef lll
240     #undef rrr
241     #undef ls
242     #undef rs
243 }T;
244 int n,m,k,t;
245 int lastans;
246 int from[N];
247 int plc[N];
248 int to[N];
249 int no[N];
250 int main()
251 {
252     scanf("%d%d%d%d",&n,&m,&k,&t);
253     for(int i=1;i<=m;i++)
254     {
255         scanf("%d%d",&from[i],&to[i]);
256         no[i]=i;
257         plc[i]=n+i;
258     }
259     T.fit(n,m);
260     P.fit(m);
261     for(int i=1;i<=m;i++)
262     {
263         P.ops(i);
264         int a=from[i],b=to[i];
265         if(a==b)
266             continue;
267         if(T.check(a,b))
268         {
269             int pos=T.minplace(a,b);
270             P.Add(i,pos,-1);
271             T.cut(plc[pos],from[pos]);
272             T.cut(plc[pos],to[pos]);
273         }
274         T.link(plc[i],a);
275         T.link(plc[i],b);
276         P.Add(i,i,1);
277     }
278     while(k--)
279     {
280         int l,r;
281         scanf("%d%d",&l,&r);
282         if(t)
283         {
284             l^=lastans;
285             r^=lastans;
286         }
287         lastans=n-P.Query(l,r);
288         printf("%d
",lastans);
289     }
290     return 0;
291 }
原文地址:https://www.cnblogs.com/blog-Dr-J/p/10116611.html