# bzoj4025

  1 type node=record
2        x,y,s,t:longint;
3      end;
4
5 var c,d,fa:array[0..100010] of longint;
6     e:array[0..200010] of node;
7     te:array[0..300010*20] of node;
8     st:array[0..300010*20] of longint;
9     ans:array[0..100010] of boolean;
10     en,top,t,n,m,len,i,x,y,a,b:longint;
11
12 procedure swap(var a,b:longint);
13   var c:longint;
14   begin
15     c:=a;
16     a:=b;
17     b:=c;
18   end;
19
20 function getf(x:longint):longint;
21   begin
22     while fa[x]<>x do x:=fa[x];  //路径压缩是均摊，所里这里不需要
23     exit(fa[x]);
24   end;
25
26 function dis(x:longint):longint;
27   begin
28     dis:=0;
29     while fa[x]<>x do
30     begin
31       dis:=dis xor c[x];
32       x:=fa[x];
33     end;
34   end;
35
36 procedure union(x,y,w:longint);
37   begin
38     if d[x]>d[y] then swap(x,y);  //按深度合并
39     fa[x]:=y;
40     inc(en);
41     st[en]:=x;
42     c[x]:=w;
43     if d[x]=d[y] then
44     begin
45       inc(en);
46       st[en]:=-y;
47       inc(d[y]);
48     end;
49   end;
50
51 procedure rebuild(be:longint);
52   var x:longint;
53   begin
54     while be<>en do  //两种情况的恢复
55     begin
56       x:=st[en];
57       if x<0 then
58         dec(d[-x])
59       else begin
60         fa[x]:=x;
61         c[x]:=0;
62       end;
63       dec(en);
64     end;
65   end;
66
68   begin
69     inc(len);
70     e[len].x:=x;
71     e[len].y:=y;
72     e[len].s:=a;
73     e[len].t:=b;
74   end;
75
76 procedure cdq(m,l,r:longint);
77   var mid,x,y,w,be,j,dow:longint;
78   begin
79     be:=en;
80     mid:=(l+r) shr 1;
81     for i:=1 to m do
82       if (e[i].s=l) and (e[i].t=r) then
83       begin
84         x:=getf(e[i].x);
85         y:=getf(e[i].y);
86         w:=dis(e[i].x) xor dis(e[i].y) xor 1;
87         if x<>y then union(x,y,w)
88         else if w=1 then
89         begin
90           for j:=l to r do
91             ans[j]:=false;
92           rebuild(be);
93           exit;
94         end;
95       end;
96     if l=r then ans[l]:=true
97     else begin
98       len:=0;
99       dow:=top;
100       for i:=1 to m do  //划分边集
101       begin
102         if (e[i].s=l) and (e[i].t=r) then continue;
103         inc(top);
104         te[top]:=e[i];
105         if e[i].t<=mid then
106         begin
107           inc(len);
108           e[len]:=e[i];
109         end
110         else if e[i].s<=mid then
112       end;
113       cdq(len,l,mid);
114       len:=0;
115       for i:=top downto dow+1 do
116         if te[i].s>mid then
117         begin
118           inc(len);
119           e[len]:=te[i];
120         end
121         else if te[i].t>mid then
123       top:=dow;
124       cdq(len,mid+1,r);
125     end;
126     rebuild(be);
127   end;
128
129 begin
131   for i:=1 to m do
132   begin
134     inc(a);
135     if a>b then continue;
137   end;
138   for i:=1 to n do
139   begin
140     fa[i]:=i;
141     d[i]:=1;
142   end;
143   cdq(m,1,t);
144   for i:=1 to t do
145     if ans[i] then writeln('Yes') else writeln('No');
146 end.
View Code

posted on 2015-05-27 14:41  acphile  阅读(1040)  评论(0编辑  收藏  举报