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 }