BZOJ4353 Play with tree[树剖]
复习几乎考不到的树剖。维护min以及min个数,打set和add标记即可,注意set优先级优于add。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define dbg(x) cerr << #x << " = " << x <<endl 7 using namespace std; 8 typedef long long ll; 9 typedef double db; 10 typedef pair<int,int> pii; 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 16 template<typename T>inline T read(T&x){ 17 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 18 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 19 } 20 const int N=1e5+7,INF=0x7f7f7f7f; 21 struct thxorz{int to,nxt;}G[N<<1]; 22 int Head[N],tot; 23 int n,q; 24 inline void Addedge(int x,int y){ 25 G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot; 26 G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot; 27 } 28 #define y G[j].to 29 int fa[N],son[N],topfa[N],st[N],dep[N],cnt,sonc[N]; 30 void dfs1(int x,int f){ 31 int tmp=-1;sonc[x]=1;fa[x]=f,dep[x]=dep[f]+1; 32 for(register int j=Head[x];j;j=G[j].nxt)if(y^f)dfs1(y,x),sonc[x]+=sonc[y],MAX(tmp,sonc[y])&&(son[x]=y); 33 } 34 void dfs2(int x,int topf){ 35 topfa[x]=topf,st[x]=cnt++;if(!son[x])return;dfs2(son[x],topf);//order the point in dfs2,not in dfs1. 36 for(register int j=Head[x];j;j=G[j].nxt)if((y^fa[x])&&(y^son[x]))dfs2(y,y); 37 } 38 #undef y 39 #define lc i<<1 40 #define rc i<<1|1 41 #define all 1,1,n-1 42 int minv[N<<2],mint[N<<2],stag[N<<2],atag[N<<2]; 43 inline void Pushup(int i){ 44 if(minv[lc]<minv[rc])mint[i]=mint[lc]; 45 else mint[i]=minv[lc]>minv[rc]?mint[rc]:mint[lc]+mint[rc]; 46 minv[i]=_min(minv[lc],minv[rc]); 47 } 48 inline void Pushdown(int i,int L,int R){ 49 if(~stag[i]){ 50 minv[lc]=minv[rc]=stag[i]+atag[i]; 51 atag[lc]=atag[rc]=atag[i],stag[lc]=stag[rc]=stag[i]; 52 mint[lc]=(L+R>>1)-L+1,mint[rc]=R-(L+R>>1); 53 stag[i]=-1,atag[i]=0; 54 } 55 else{ 56 minv[lc]+=atag[i],minv[rc]+=atag[i]; 57 atag[lc]+=atag[i],atag[rc]+=atag[i]; 58 atag[i]=0; 59 } 60 } 61 void Build(int i,int L,int R){ 62 if(L==R){mint[i]=1,stag[i]=-1;return;} 63 int mid=L+R>>1;Build(lc,L,mid),Build(rc,mid+1,R),Pushup(i),stag[i]=-1; 64 } 65 void Update_set(int i,int L,int R,int ql,int qr,int c){ 66 if(ql<=L&&qr>=R){minv[i]=c,mint[i]=R-L+1,stag[i]=c,atag[i]=0;return;} 67 int mid=L+R>>1;Pushdown(i,L,R); 68 if(ql<=mid)Update_set(lc,L,mid,ql,qr,c); 69 if(qr>mid)Update_set(rc,mid+1,R,ql,qr,c); 70 Pushup(i); 71 } 72 void Update_add(int i,int L,int R,int ql,int qr,int c){ 73 if(ql<=L&&qr>=R){minv[i]+=c,atag[i]+=c;return;} 74 int mid=L+R>>1;Pushdown(i,L,R); 75 if(ql<=mid)Update_add(lc,L,mid,ql,qr,c); 76 if(qr>mid)Update_add(rc,mid+1,R,ql,qr,c); 77 Pushup(i); 78 } 79 int Query_min(int i,int L,int R,int ql,int qr){//dbg(i),dbg(ql),dbg(qr),dbg(minv[i]); 80 if(ql<=L&&qr>=R)return minv[i]; 81 int mid=L+R>>1,ret=INF;Pushdown(i,L,R); 82 if(ql<=mid)MIN(ret,Query_min(lc,L,mid,ql,qr)); 83 if(qr>mid)MIN(ret,Query_min(rc,mid+1,R,ql,qr)); 84 return ret; 85 } 86 inline void Tree_set(int x,int y,int c){ 87 while(topfa[x]^topfa[y]){ 88 if(dep[topfa[x]]<dep[topfa[y]])swap(x,y);//dbg(x);dbg(y); 89 Update_set(all,st[topfa[x]],st[x],c);x=fa[topfa[x]]; 90 } 91 if(dep[x]>dep[y])swap(x,y); 92 if(x^y)Update_set(all,st[x]+1,st[y],c); 93 } 94 inline int Tree_min(int x,int y){ 95 int ret=INF; 96 while(topfa[x]^topfa[y]){ 97 if(dep[topfa[x]]<dep[topfa[y]])swap(x,y);//dbg(x),dbg(st[topfa[x]]),dbg(st[x]); 98 MIN(ret,Query_min(all,st[topfa[x]],st[x]));x=fa[topfa[x]]; 99 } 100 if(dep[x]>dep[y])swap(x,y); 101 if(x^y)MIN(ret,Query_min(all,st[x]+1,st[y])); 102 return ret; 103 } 104 inline void Tree_add(int x,int y,int c){ 105 int minx=Tree_min(x,y);//dbg(minx); 106 if(minx+c<0)c=-minx; 107 while(topfa[x]^topfa[y]){ 108 if(dep[topfa[x]]<dep[topfa[y]])swap(x,y); 109 Update_add(all,st[topfa[x]],st[x],c);x=fa[topfa[x]]; 110 } 111 if(dep[x]>dep[y])swap(x,y); 112 if(x^y)Update_add(all,st[x]+1,st[y],c); 113 } 114 int main(){//freopen("3.in","r",stdin);freopen("test.ans","w",stdout); 115 read(n);read(q); 116 for(register int i=1,x,y;i<n;++i)read(x),read(y),Addedge(x,y); 117 dfs1(1,0);dfs2(1,1);Build(all);//for(register int i=1;i<=n;++i)cout<<i<<" ",dbg(st[i]); 118 for(register int i=1,opt,x,y,c;i<=q;++i){ 119 read(opt),read(x),read(y),read(c); 120 if(opt==1)Tree_set(x,y,c); 121 else Tree_add(x,y,c); 122 printf("%d\n",!minv[1]?mint[1]:0); 123 } 124 return 0; 125 }