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 }
View Code

 

转载于:https://www.cnblogs.com/saigyouji-yuyuko/p/11573850.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值