好题+数据结构神题+感人肺腑pascal被卡系列,我下面的代码几乎写到最优
可怎耐bzoj上pascal开的是O1,c++开的是O2,这怎么可能跑得过!!!
还是说说方法吧,这是一道算贡献的好题,因为我们不可能把边加进去依次算连通块个数
我们考虑在区间[l,r]中每条边i是否能使两个连通块变成1个,什么样的边可以呢?
显然,这条边端点所在的连通块在i加入之前不连通或者是使这两个连通块相连的边号<l
这样算法就呼之欲出了,我们首先依次把边i加入,如果构成环,则弹出环上编号最小的边并记录,否则记为0
这里我们可以用link cut tree解决
下面每次询问,我们只要求[l,r]有多少个数小于l即可
这题有是否强制在线两种情况,在线可以直接rush,但是我第一次TLE之后又写了一遍离线,发现比原来快但还是远远慢于只在线的c++,实在没办法只好弃疗,说一下两种情况
在线:显然这是主席树的经典问题
离线:注意这个个数是满足区间减法的,于是我们可以拆成两个求前缀询问并排序(注意这里用计数排序才有显著的提升),然后按边编号的顺序依次加入然后用树状数组统计,具体见程序

  1 const inf=100000007;
  2 type node=record
  3        l,r,s:longint;
  4      end;
  5      way=record
  6        s,e:longint;
  7      end;
  8      point=record
  9        be,op,y:longint;
 10      end;
 11      xxx=record
 12        po,next:longint;
 13      end;
 14 
 15 var son:array[0..400010,1..2] of longint;
 16     q,w,v,fa:array[0..400010] of longint;
 17     qq:array[0..410010] of point;
 18     ee:array[0..400010] of xxx;
 19     rev:array[0..400010] of boolean;
 20     tree:array[0..200010*22] of node;
 21     e:array[0..200010] of way;
 22     p,f,a,h,anss:array[0..200010] of longint;
 23     len,j,k1,k2,n,m,k,ty,t,i,ans,l,r,mm:longint;
 24 
 25 function min(a,b:longint):longint;
 26   begin
 27     if w[a]>w[b] then exit(b) else exit(a);
 28   end;
 29 
 30 function getf(x:longint):longint;
 31   begin
 32     if f[x]<>x then f[x]:=getf(f[x]);
 33     exit(f[x]);
 34   end;
 35 
 36 procedure swap(var a,b:longint);
 37   var c:longint;
 38   begin
 39     c:=a;
 40     a:=b;
 41     b:=c;
 42   end;
 43 
 44 function root(x:longint):boolean;
 45   begin
 46     exit((son[fa[x],1]<>x) and (son[fa[x],2]<>x));
 47   end;
 48 
 49 procedure update(x:longint);
 50   begin
 51     v[x]:=min(x,min(v[son[x,1]],v[son[x,2]]));
 52   end;
 53 
 54 procedure push(x:longint);
 55   begin
 56     if rev[x] then
 57     begin
 58       swap(son[x,1],son[x,2]);
 59       rev[son[x,1]]:=not rev[son[x,1]];
 60       rev[son[x,2]]:=not rev[son[x,2]];
 61       rev[x]:=false;
 62     end;
 63   end;
 64 
 65 procedure rotate(x,w:longint);
 66   var y:longint;
 67   begin
 68     y:=fa[x];
 69     if not root(y) then
 70     begin
 71       if son[fa[y],1]=y then son[fa[y],1]:=x
 72       else son[fa[y],2]:=x;
 73     end;
 74     fa[x]:=fa[y];
 75     son[y,3-w]:=son[x,w];
 76     if son[x,w]<>0 then fa[son[x,w]]:=y;
 77     son[x,w]:=y;
 78     fa[y]:=x;
 79     update(y);
 80   end;
 81 
 82 procedure splay(x:longint);
 83   var i,s,y:longint;
 84       fl:boolean;
 85   begin
 86     i:=x;
 87     s:=0;
 88     while not root(i) do
 89     begin
 90       inc(s);
 91       q[s]:=i;
 92       i:=fa[i];
 93     end;
 94     inc(s);
 95     q[s]:=i;
 96     for i:=s downto 1 do
 97       push(q[i]);
 98     if s=1 then exit;
 99     fl:=true;
100     while fl do
101     begin
102       y:=fa[x];
103       if y=q[s] then
104       begin
105         if son[y,1]=x then rotate(x,2)
106         else rotate(x,1);
107         fl:=false;
108       end
109       else begin
110         if fa[y]=q[s] then fl:=false;
111         if son[fa[y],1]=y then
112         begin
113           if son[y,1]=x then rotate(y,2)
114           else rotate(x,1);
115           rotate(x,2);
116         end
117         else begin
118           if son[y,1]=x then rotate(x,2)
119           else rotate(y,1);
120           rotate(x,1);
121         end;
122       end;
123     end;
124     update(x);
125   end;
126 
127 procedure access(x:longint);
128   var y:longint;
129   begin
130     y:=0;
131     repeat
132       splay(x);
133       son[x,2]:=y;
134       update(x);
135       y:=x;
136       x:=fa[x];
137     until x=0;
138   end;
139 
140 procedure makeroot(x:longint);
141   begin
142     access(x);
143     splay(x);
144     rev[x]:=not rev[x];
145   end;
146 
147 procedure link(x,y:longint);
148   begin
149     makeroot(x);
150     fa[x]:=y;
151   end;
152 
153 procedure path(x,y:longint);
154   begin
155     makeroot(x);
156     access(y);
157     splay(y);
158   end;
159 
160 procedure cut(x,y:longint);
161   begin
162     path(x,y);
163     son[y,1]:=0;
164     fa[x]:=0;
165   end;
166 
167 function build(l,r:longint):longint;
168   var m,q:longint;
169   begin
170     inc(t);
171     if l=r then exit(t)
172     else begin
173       m:=(l+r) shr 1;
174       q:=t;
175       tree[q].l:=build(l,m);
176       tree[q].r:=build(m+1,r);
177       exit(q);
178     end;
179   end;
180 
181 function add(l,r,last,x:longint):longint;
182   var m,q:longint;
183   begin
184     inc(t);
185     if l=r then
186     begin
187       tree[t].s:=tree[last].s+1;
188       exit(t);
189     end
190     else begin
191       m:=(l+r) shr 1;
192       q:=t;
193       if x<=m then
194       begin
195         tree[q].r:=tree[last].r;
196         tree[q].l:=add(l,m,tree[last].l,x);
197       end
198       else begin
199         tree[q].l:=tree[last].l;
200         tree[q].r:=add(m+1,r,tree[last].r,x);
201       end;
202       tree[q].s:=tree[tree[q].l].s+tree[tree[q].r].s;
203       exit(q);
204     end;
205   end;
206 
207 function ask(l,r,x,y:longint):longint;
208   var m,s:longint;
209   begin
210     if l=r then exit(tree[y].s-tree[x].s)
211     else begin
212       m:=(l+r) shr 1;
213       if k1<=m then exit(ask(l,m,tree[x].l,tree[y].l))
214       else begin
215         s:=tree[tree[y].l].s-tree[tree[x].l].s;
216         exit(s+ask(m+1,r,tree[x].r,tree[y].r));
217       end;
218     end;
219   end;
220 
221 procedure cha(var a,b:point);
222   var c:point;
223   begin
224     c:=a;
225     a:=b;
226     b:=c;
227   end;
228 
229 function lowbit(x:longint):longint;
230   begin
231     exit(x and (-x));
232   end;
233 
234 procedure jia(x,y:longint);
235   begin
236     inc(len);
237     ee[len].po:=y;
238     ee[len].next:=p[x];
239     p[x]:=len;
240   end;
241 
242 procedure ins(x:longint);
243   begin
244     while x<=m+1 do
245     begin
246       inc(h[x]);
247       x:=x+lowbit(x);
248     end;
249   end;
250 
251 function an(x:longint):longint;
252   begin
253     an:=0;
254     while x>0 do
255     begin
256       an:=an+h[x];
257       x:=x-lowbit(x);
258     end;
259   end;
260 
261 begin
262   readln(n,m,k,ty);
263   for i:=1 to n do
264   begin
265     f[i]:=i;
266     w[i]:=inf;
267   end;
268   t:=n;
269   w[0]:=inf;
270   for i:=1 to m do
271   begin
272     readln(e[i].s,e[i].e);
273     if e[i].s=e[i].e then
274     begin
275       a[i]:=i;
276       continue;
277     end;
278     k1:=getf(e[i].s);
279     k2:=getf(e[i].e);
280     if k1=k2 then  //并查集判连通
281     begin
282       path(e[i].s,e[i].e);
283       l:=v[e[i].e];
284       a[i]:=w[l];
285       cut(e[w[l]].s,l);
286       cut(e[w[l]].e,l);
287     end
288     else f[k1]:=k2;
289     inc(t);  w[t]:=i;
290     link(e[i].s,t);
291     link(e[i].e,t);
292   end;
293   if ty=1 then  //在线做法
294   begin
295     t:=0;
296     h[0]:=build(0,m);
297     for i:=1 to m do
298     begin
299       h[i]:=add(0,m,h[i-1],a[i]);
300     end;
301     ans:=0;
302     for i:=1 to k do
303     begin
304       readln(l,r);
305       l:=l xor ans;
306       r:=r xor ans;
307       if l>r then swap(l,r);
308       k1:=l-1;
309       ans:=n-ask(0,m,h[l-1],h[r]);
310       writeln(ans);
311     end;
312   end
313   else begin  //离线做法
314     t:=0;
315     for i:=1 to k do
316     begin
317       readln(l,r);
318       inc(t);
319       qq[t].op:=-1;
320       qq[t].y:=l;
321       qq[t].be:=i;
322       jia(r,t);
323       inc(t);
324       qq[t].op:=1;
325       jia(l-1,t);
326       qq[t].y:=l;
327       qq[t].be:=i;
328     end;
329     j:=1;
330     a[m+1]:=inf;
331     for i:=0 to m do 
332     begin
333       while j<=i do
334       begin
335         ins(a[j]+1); //树状数组编号从1开始,所以+1
336         inc(j);
337       end;
338       l:=p[i];
339       while l<>0 do
340       begin
341         r:=ee[l].po;
342         inc(anss[qq[r].be],qq[r].op*an(qq[r].y));
343         l:=ee[l].next;
344       end;
345     end;
346     for i:=1 to k do
347       writeln(anss[i]+n);
348   end;
349 end.  
View Code

 

posted on 2015-04-05 22:51  acphile  阅读(197)  评论(0编辑  收藏  举报