BYRBT

BZOJ 3514 Codechef MARCH14 GERALD07加强版

从CC抠的题 xyz大神直接用分块秒 虽然会MLE+TLE

 

时限被改成40s了,我觉得30s足够了吧……

 

考虑从左至右加入每一条边,加入某条边成环的环那么这条边对答案就没有影响。那么只要环上标号最小的边没被加入就会对答案有影响。

 

所以问题变成了区间询问小于某个数的数有多少个,这个主席树就行了。

 

至于前面那一步,用动态树求出来就行了。

 

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<cctype>
  5 #include<algorithm>
  6  
  7 using namespace std;
  8  
  9 const int BUF_SIZE = 30;
 10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
 11   
 12 #define PTR_NEXT() \
 13     { \
 14         buf_s ++; \
 15         if (buf_s == buf_t) \
 16         { \
 17             buf_s = buf; \
 18             buf_t = buf + fread(buf, 1, BUF_SIZE, stdin); \
 19         } \
 20     }
 21    
 22 #define readint(_n_) \
 23     { \
 24         while (*buf_s != '-' && !isdigit(*buf_s)) \
 25             PTR_NEXT(); \
 26         bool register _nega_ = false; \
 27         if (*buf_s == '-') \
 28         { \
 29             _nega_ = true; \
 30             PTR_NEXT(); \
 31         } \
 32         int register _x_ = 0; \
 33         while (isdigit(*buf_s)) \
 34         { \
 35             _x_ = _x_ * 10 + *buf_s - '0'; \
 36             PTR_NEXT(); \
 37         } \
 38         if (_nega_) \
 39             _x_ = -_x_; \
 40         (_n_) = (_x_); \
 41     }
 42 
 43 const int maxn=200010;
 44 const int maxp=maxn*20;
 45 const int INF=0x3f3f3f3f;
 46  
 47 int n,m,k,wmt,type,s[maxn],e[maxn],root[maxn];
 48  
 49 struct tree_node
 50 {
 51     int l,r;
 52     int sum;
 53     void init()
 54     {
 55         l=r=sum=0;
 56     }
 57 }y[maxp];
 58  
 59 int newnode()
 60 {
 61     y[++wmt].init();
 62     return wmt;
 63 }
 64  
 65 int insert(int p,int l,int r,int v)
 66 {
 67     int pp=newnode();
 68     if (l==r)
 69     {
 70         y[pp].sum=y[p].sum+1;
 71         return pp;
 72     }
 73     int m=(l+r)>>1;
 74     if (v<=m)
 75     {
 76         y[pp].l=insert(y[p].l,l,m,v);
 77         y[pp].r=y[p].r;
 78     }
 79     else
 80     {
 81         y[pp].l=y[p].l;
 82         y[pp].r=insert(y[p].r,m+1,r,v);
 83     }
 84     y[pp].sum=y[y[pp].l].sum+y[y[pp].r].sum;
 85     return pp;
 86 }
 87  
 88 int query(int p1,int p2,int l,int r,int nowl,int nowr)
 89 {
 90     if (nowl<=l && r<=nowr) return y[p1].sum-y[p2].sum;
 91     int m=(l+r)>>1;
 92     if (nowl<=m)
 93     {
 94         if (m<nowr) return query(y[p1].l,y[p2].l,l,m,nowl,nowr)+query(y[p1].r,y[p2].r,m+1,r,nowl,nowr);
 95         else return query(y[p1].l,y[p2].l,l,m,nowl,nowr);
 96     }
 97     else return query(y[p1].r,y[p2].r,m+1,r,nowl,nowr);
 98 }
 99  
100 struct node
101 {
102     int l,r,f,v,minv;
103     bool rev,rt;
104     void init()
105     {
106         l=r=f=0;
107         rev=false;
108         rt=true;
109         minv=INF;
110     }
111 }z[maxn<<1];
112  
113 void update(int x)
114 {
115     z[x].minv=z[x].v;
116     if (z[x].l) z[x].minv=min(z[x].minv,z[z[x].l].minv);
117     if (z[x].r) z[x].minv=min(z[x].minv,z[z[x].r].minv);
118 }
119  
120 void rot_l(int x)
121 {
122     int y=z[x].r;
123     z[x].r=z[y].l;
124     z[y].l=x;
125     if (z[x].rt) z[x].rt^=1,z[y].rt^=1;
126     else
127     {
128         if (z[z[x].f].l==x) z[z[x].f].l=y;
129         else z[z[x].f].r=y;
130     }
131     z[y].f=z[x].f;
132     z[x].f=y;
133     z[z[x].r].f=x;
134 }
135  
136 void rot_r(int x)
137 {
138     int y=z[x].l;
139     z[x].l=z[y].r;
140     z[y].r=x;
141     if (z[x].rt) z[x].rt^=1,z[y].rt^=1;
142     else
143     {
144         if (z[z[x].f].l==x) z[z[x].f].l=y;
145         else z[z[x].f].r=y;
146     }
147     z[y].f=z[x].f;
148     z[x].f=y;
149     z[z[x].l].f=x;
150 }
151  
152 void push(int x)
153 {
154     if (z[x].rev)
155     {
156         z[z[x].l].rev^=1;
157         swap(z[z[x].l].l,z[z[x].l].r);
158         z[z[x].r].rev^=1;
159         swap(z[z[x].r].l,z[z[x].r].r);
160         z[x].rev^=1;
161     }
162 }
163  
164 void splay(int x)
165 {
166     while (!z[x].rt)
167     {
168         int f=z[x].f;
169         int ff=z[f].f;
170         push(ff);
171         push(f);
172         push(x);
173         if (z[f].rt)
174         {
175             if (z[f].l==x) rot_r(f);
176             else rot_l(f);
177         }
178         else
179         {
180             if (z[ff].l==f && z[f].l==x)
181             {
182                 rot_r(ff);
183                 rot_r(f);
184             }
185             if (z[ff].l==f && z[f].r==x)
186             {
187                 rot_l(f);
188                 rot_r(ff);
189             }
190             if (z[ff].r==f && z[f].l==x)
191             {
192                 rot_r(f);
193                 rot_l(ff);
194             }
195             if (z[ff].r==f && z[f].r==x)
196             {
197                 rot_l(ff);
198                 rot_l(f);
199             }
200         }
201         update(ff);
202         update(f);
203     }
204     update(x);
205     push(x);
206 }
207  
208 void access(int x)
209 {
210     int p1=x,p2=0;
211     do
212     {
213         splay(p1);
214         z[z[p1].r].rt=true;
215         z[p2].rt=false;
216         z[p1].r=p2;
217         z[p2].f=p1;
218         update(p1);
219         p2=p1;
220         p1=z[p1].f;
221     }while(p1);
222 }
223  
224 void join(int p1,int p2)
225 {
226     access(p1);
227     splay(p1);
228     z[p1].rev^=1;
229     swap(z[p1].l,z[p1].r);
230     z[p1].f=p2;
231 }
232  
233 void cut(int p1,int p2)
234 {
235     access(p1);
236     splay(p2);
237     if (z[p2].f==p1) z[p2].f=0;
238     else
239     {
240         access(p2);
241         splay(p1);
242         z[p1].f=0;
243     }
244 }
245  
246 bool connect(int p1,int p2)
247 {
248     access(p2);
249     for (;p1;p1=z[p1].f)
250     {
251         splay(p1);
252         if (!z[p1].f) break;
253     }
254     for (;z[p1].r;p1=z[p1].r);
255     return p1==p2;
256 }
257  
258 int query(int x,int y)
259 {
260     access(y);
261     int ans=INF;
262     for (y=0;x;x=z[x].f)
263     {
264         splay(x);
265         if (!z[x].f)
266         {
267             ans=z[x].v;
268             if (y) ans=min(ans,z[y].minv);
269             if (z[x].r) ans=min(ans,z[z[x].r].minv);
270             break;
271         }
272         z[z[x].r].rt=true;
273         z[y].rt=false;
274         z[x].r=y;
275         y=x;
276         update(y);
277     }
278     return ans;
279 }
280  
281  
282 int main()
283 {
284 
285     readint(n);
286     readint(m);
287     readint(k);
288     readint(type);
289     for (int a=1;a<=m;a++)
290     {
291         readint(s[a]);
292         readint(e[a]);
293     }
294     for (int a=1;a<=n+m;a++)
295     {
296         z[a].init();
297         if (a<=n) z[a].v=z[a].minv=INF;
298         else z[a].v=z[a].minv=a-n;
299     }
300     wmt=0;
301     for (int a=1;a<=m;a++)
302     {
303         int p1=s[a],p2=e[a];
304         if (p1==p2)
305         {
306             root[a]=insert(root[a-1],0,m,a);
307             continue;
308         }
309         if (connect(p1,p2))
310         {
311             int value=query(p1,p2);
312             cut(value+n,s[value]);
313             cut(value+n,e[value]);
314             root[a]=insert(root[a-1],0,m,value);
315             join(a+n,p1);
316             join(a+n,p2);
317         }
318         else 
319         {
320             root[a]=insert(root[a-1],0,m,0);
321             join(a+n,p1);
322             join(a+n,p2);
323         }
324     }
325     int l,r;
326     for (int a=1,lastans=0;a<=k;a++)
327     {
328         readint(l);
329         readint(r);
330         if (type==1) l^=lastans,r^=lastans;
331         printf("%d\n",(lastans=n-query(root[r],root[l-1],0,m,0,l-1)));
332     }
333 
334     return 0;
335 }
View Code

 

posted @ 2014-04-08 11:25 zhonghaoxi 阅读(...) 评论(...) 编辑 收藏
BYRBT