【BZOJ4025】二分图 LCT
1 /************************************************************** 2 Problem: 4025 3 User: sumjune 4 Language: C++ 5 Result: Accepted 6 Time:7924 ms 7 Memory:24340 kb 8 ****************************************************************/ 9 10 #include<bits/stdc++.h> 11 #define F(i,a,b) for(int i=a;i<=b;++i) 12 #define D(i,a,b) for(int i=a;i>=b;i--) 13 #define GT() getchar() 14 #define LL long long 15 using namespace std; 16 const int N=1e5+5; 17 int n,m,sz,cnt,odd,T; 18 struct data{ 19 int x,y,t,opt,id; 20 bool operator < (const data &a) const { 21 return t<a.t||t==a.t&&opt>a.opt; 22 } 23 } e[N<<2]; 24 int fl[N<<1],tree[N<<1],l[N*3],r[N*3],pt[N<<1],re[N*3],val[N*3]; 25 int f[N*3],ch[N*3][2],size[N*3],rev[N*3],mn[N*3],sta[N*3]; 26 namespace LCT{ 27 bool isroot(int x) {return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;} 28 int get(int x) {return ch[f[x]][1]==x;} 29 void update(int x) { size[x]=1; int loc=x; 30 if(ch[x][0]) { size[x]+=size[ch[x][0]]; 31 if(val[mn[ch[x][0]]]<val[loc]) loc=mn[ch[x][0]]; 32 } if(ch[x][1]){size[x]+=size[ch[x][1]]; 33 if(val[mn[ch[x][1]]]<val[loc]) loc=mn[ch[x][1]]; 34 } mn[x]=loc; 35 } void pushdown(int x) { 36 if(rev[x]&&x) { 37 if(ch[x][0]) rev[ch[x][0]]^=1; 38 if(ch[x][1]) rev[ch[x][1]]^=1; 39 swap(ch[x][0],ch[x][1]); rev[x]=0; 40 } 41 } void rotate(int x) { 42 int y=f[x],z=f[y],k=get(x); 43 if(!isroot(y)) ch[z][ch[z][1]==y]=x; f[x]=z; ch[y][k]=ch[x][k^1]; 44 if(ch[y][k]) f[ch[y][k]]=y; ch[x][k^1]=y; f[y]=x; update(y),update(x); 45 } void splay(int x) { 46 int top=0;sta[++top]=x; 47 for(int i=x;!isroot(i);i=f[i]) sta[++top]=f[i]; 48 for(int i=top;i;i--) pushdown(sta[i]); 49 for(int fa;!isroot(x);rotate(x)) if(!isroot(fa=f[x])) rotate((get(fa)==get(x))?fa:x); 50 } void access(int x) {int t=0;for(;x;t=x,x=f[x]) splay(x),ch[x][1]=t,update(x); } 51 void reverse(int x) {access(x);splay(x);rev[x]^=1;} 52 void link(int x,int y) {reverse(x);f[x]=y;} 53 void cut(int x,int y) {reverse(x); access(y); splay(y); ch[y][0]=f[x]=0;} 54 int find(int x) {access(x);splay(x);while(ch[x][0]) x=ch[x][0]; return x;} 55 } using namespace LCT; 56 void add(int i) { 57 int x=e[i].x,y=e[i].y,t=e[i].opt,id=e[i].id; 58 if(x==y) {fl[id]=1;++odd;return;} 59 if(find(x)==find(y)) { 60 reverse(x),access(y),splay(y); 61 int loc=mn[y],num=size[y]>>1; 62 if(val[loc]>=t) {if(!(num&1)) ++odd,fl[id]=1; return;} 63 else {if(!(num&1)) ++odd,fl[re[loc]]=1; cut(loc,l[loc]),cut(loc,r[loc]),tree[re[loc]];} 64 }++sz; val[sz]=t,pt[id]=sz,re[sz]=id; l[sz]=x,r[sz]=y; link(x,sz),link(y,sz),tree[id]=1; 65 } 66 int main(){ 67 // freopen("5.in","r",stdin);freopen("TA.out","w",stdout); 68 scanf("%d%d%d",&n,&m,&T); 69 F(i,1,m) { int x,y,z,ed; 70 scanf("%d%d%d%d",&x,&y,&z,&ed); if(x>y) swap(x,y); 71 e[++cnt]=(data){x,y,z,ed,i}; e[++cnt]=(data){x,y,ed,-1,i}; 72 } sort(e+1,e+cnt+1); 73 memset(val,127,sizeof(val)); int now=1;sz=n,odd=0; 74 F(i,0,T-1) { 75 for(;now<=cnt&&e[now].t<=i;++now) 76 if(e[now].opt==-1) { 77 odd-=fl[e[now].id]; fl[e[now].id]=0; 78 if(tree[e[now].id]) tree[e[now].id]=0, 79 cut(pt[e[now].id],l[pt[e[now].id]]), 80 cut(pt[e[now].id],r[pt[e[now].id]]); 81 } else add(now); 82 if(odd) puts("No");else puts("Yes"); 83 } 84 return 0; 85 }