bzoj4712 -- 树链剖分

来源:互联网 发布:手机虚拟试衣软件 编辑:程序博客网 时间:2024/06/13 18:42

 题解

代码:


  1 #include<iostream>  2 #include<cstdio>  3 #include<cstring>  4 #include<algorithm>  5 #include<vector>  6 using namespace std;  7 #define N 200010  8 #define ll long long  9 #define INF 1LL<<60 10 vector<int>g[N]; 11 ll p[N<<2],c[N<<2],h[N],dp[N],w[N],y,d; 12 int i,j,k,n,m,Top[N],Num,s[N],W[N],W2[N],f[N],x,Son[N]; 13 char S[3]; 14 inline ll Min(ll x,ll y){return x<y?x:y;} 15 inline void Dfs(int x,int F){ 16     f[x]=F;s[x]=1; 17     for(int i=0;i<g[x].size();i++) 18     if(g[x][i]!=F){ 19         Dfs(g[x][i],x); 20         if(s[g[x][i]]>s[Son[x]])Son[x]=g[x][i]; 21         s[x]+=s[g[x][i]]; 22         h[x]+=dp[g[x][i]]; 23     } 24     if(s[x]==1)h[x]=INF; 25     dp[x]=Min(w[x],h[x]); 26 } 27 inline void Dfs2(int x,int Tmp){ 28     Top[x]=Tmp;W[x]=++Num;W2[Num]=x; 29     if(Son[x])Dfs2(Son[x],Tmp); 30     for(int i=0;i<g[x].size();i++) 31     if(g[x][i]!=f[x]&&g[x][i]!=Son[x])Dfs2(g[x][i],g[x][i]); 32 } 33 inline void Push(int Node){ 34     c[Node<<1]-=p[Node];c[Node<<1|1]-=p[Node]; 35     p[Node<<1]+=p[Node];p[Node<<1|1]+=p[Node]; 36     p[Node]=0; 37 } 38 inline int Find(int Node,int l,int r,int L,int R,ll x){ 39     if(l>=L&&r<=R){ 40         if(c[Node]>=x)return l; 41         if(l==r)return 0; 42     } 43     if(p[Node])Push(Node); 44     int Mid=l+r>>1; 45     if(Mid>=R)return Find(Node<<1,l,Mid,L,R,x); 46     if(Mid<L)return Find(Node<<1|1,Mid+1,r,L,R,x); 47     int y=Find(Node<<1|1,Mid+1,r,L,R,x); 48     if(y==0||y>Mid+1)return y; 49     y=Find(Node<<1,l,Mid,L,R,x); 50     if(y)return y; 51     return Mid+1; 52 } 53 inline int Get_top(int x,ll d){ 54     int t=x; 55     while(x){ 56         int y=Find(1,1,n,W[Top[x]],W[x],d); 57         if(y==0)break; 58         if(y>W[Top[x]])return W2[y]; 59         t=Top[x]; 60         x=f[t]; 61     } 62     return t; 63 } 64 inline void Build(int Node,int l,int r){ 65     if(l==r){ 66         c[Node]=w[W2[l]]-h[W2[l]]; 67         p[Node]=h[W2[l]]; 68         return; 69     } 70     int Mid=l+r>>1; 71     Build(Node<<1,l,Mid); 72     Build(Node<<1|1,Mid+1,r); 73     c[Node]=Min(c[Node<<1],c[Node<<1|1]); 74 } 75 inline ll Query(int Node,int l,int r,int x){ 76     if(l==r)return p[Node]; 77     if(p[Node])Push(Node); 78     int Mid=l+r>>1; 79     if(x<=Mid)return Query(Node<<1,l,Mid,x); 80     return Query(Node<<1|1,Mid+1,r,x); 81 } 82 inline ll Query_dp(int x){return Min(w[x],Query(1,1,n,W[x]));} 83 inline void Update_w(int Node,int l,int r,int x,ll y){ 84     if(l==r){c[Node]+=y;return;} 85     int Mid=l+r>>1; 86     if(p[Node])Push(Node); 87     if(Mid>=x)Update_w(Node<<1,l,Mid,x,y);else Update_w(Node<<1|1,Mid+1,r,x,y); 88     c[Node]=Min(c[Node<<1],c[Node<<1|1]);     89 } 90 inline void Update_h(int Node,int l,int r,int L,int R,ll x){ 91     if(l>R||r<L)return; 92     if(l>=L&&r<=R){ 93         c[Node]-=x; 94         p[Node]+=x; 95         return; 96     } 97     if(p[Node])Push(Node); 98     int Mid=l+r>>1; 99     Update_h(Node<<1,l,Mid,L,R,x);100     Update_h(Node<<1|1,Mid+1,r,L,R,x);101     c[Node]=Min(c[Node<<1],c[Node<<1|1]);102 }103 inline void Modify(int x,int y,ll z){104     while(Top[x]!=Top[y])Update_h(1,1,n,W[Top[x]],W[x],z),x=f[Top[x]];105     Update_h(1,1,n,W[y],W[x],z);106 }107 inline void Update_tree(int x,ll y){108     ll Tmp=Query_dp(x);109     w[x]+=y;Update_w(1,1,n,W[x],y);110     d=Query_dp(x)-Tmp;111     if(d==0)return;112     while(f[x]){113         int z=Get_top(x,d);114         if(x!=z)Modify(f[x],z,d);115         x=f[z];116         if(x==0)return;117         ll Tmp=Query_dp(x);118         Update_h(1,1,n,W[x],W[x],d);119         d=Query_dp(x)-Tmp;120         if(d==0)return;121     }122 }123 int main(){124     scanf("%d",&n);125     for(i=1;i<=n;i++)scanf("%lld",&w[i]);126     for(i=1;i<n;i++)scanf("%d%d",&x,&y),g[x].push_back(y),g[y].push_back(x);127     Dfs(1,0);Dfs2(1,1);128     Build(1,1,n);129     scanf("%d",&m);130     while(m--){131         scanf("%s",S);132         if(S[0]=='Q')scanf("%d",&x),printf("%lld\n",Query_dp(x));else scanf("%d%lld",&x,&y),Update_tree(x,y);133     }134     return 0;135 }