zoukankan      html  css  js  c++  java
  • bzoj4712 -- 树链剖分

    题解:http://www.cnblogs.com/clrs97/p/6006305.html

    代码:

      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
    ",Query_dp(x));else scanf("%d%lld",&x,&y),Update_tree(x,y);
    133     }
    134     return 0;
    135 }
    bzoj4712
  • 相关阅读:
    读取csv遇到的双循环
    hadoop环境配置
    mysql的查询
    mysql的基本操作
    mysql与python的交互
    设置自动获取IP和DNS
    pyecharts绘制地图
    集合 set方法
    字符串 string方法
    字典 dict方法
  • 原文地址:https://www.cnblogs.com/gjghfd/p/6758243.html
Copyright © 2011-2022 走看看