【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 }
原文地址:https://www.cnblogs.com/sumjune/p/9516285.html