zoukankan      html  css  js  c++  java
  • BZOJ4712: 洪水(树链剖分维护Dp)

    Description

    小A走到一个山脚下,准备给自己造一个小屋。这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到
    山顶放了格水。于是小A面前出现了一个瀑布。作为平民的小A只好老实巴交地爬山堵水。那么问题来了:我们把这
    个瀑布看成是一个n个节点的树,每个节点有权值(爬上去的代价)。小A要选择一些节点,以其权值和作为代价将
    这些点删除(堵上),使得根节点与所有叶子结点不连通。问最小代价。不过到这还没结束。小A的朋友觉得这样
    子太便宜小A了,于是他还会不断地修改地形,使得某个节点的权值发生变化。不过到这还没结束。小A觉得朋友做
    得太绝了,于是放弃了分离所有叶子节点的方案。取而代之的是,每次他只要在某个子树中(和子树之外的点完全
    无关)。于是他找到你。

    Input

     输入文件第一行包含一个数n,表示树的大小。

    接下来一行包含n个数,表示第i个点的权值。
    接下来n-1行每行包含两个数fr,to。表示书中有一条边(fr,to)。
    接下来一行一个整数,表示操作的个数。
    接下来m行每行表示一个操作,若该行第一个数为Q,则表示询问操作,后面跟一个参数x,表示对应子树的根;若
    为C,则表示修改操作,后面接两个参数x,to,表示将点x的权值加上to。
    n<=200000,保证任意to都为非负数

    Output

     对于每次询问操作,输出对应的答案,答案之间用换行隔开。

    Sample Input

    4
    4 3 2 1
    1 2
    1 3
    4 2
    4
    Q 1
    Q 2
    C 4 10
    Q 1

    Sample Output

    3
    1
    4

    解题思路:

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll spc<<1
      5 #define rrr spc<<1|1
      6 typedef long long lnt;
      7 const int N=200010;
      8 struct trnt{
      9     lnt minv;
     10     lnt lzt;
     11 }tr[N<<2];
     12 struct pnt{
     13     int hd;
     14     int fa;
     15     int tp;
     16     int dp;
     17     int wgt;
     18     int mxs;
     19     int ind;
     20     lnt val;
     21     lnt f;
     22     lnt sigf;
     23 }p[N];
     24 struct ent{
     25     int twd;
     26     int lst;
     27 }e[N<<1];
     28 int cnt;
     29 int n,m;
     30 int dfn;
     31 int plc[N];
     32 char cmd[100];
     33 void ade(int f,int t)
     34 {
     35     cnt++;
     36     e[cnt].twd=t;
     37     e[cnt].lst=p[f].hd;
     38     p[f].hd=cnt;
     39     return ;
     40 }
     41 void Basic_dfs(int x,int f)
     42 {
     43     p[x].fa=f;
     44     p[x].dp=p[f].dp+1;
     45     p[x].wgt=1;
     46     int maxs=-1;
     47     for(int i=p[x].hd;i;i=e[i].lst)
     48     {
     49         int to=e[i].twd;
     50         if(to==f)
     51             continue;
     52         Basic_dfs(to,x);
     53         p[x].sigf+=p[to].f;
     54         p[x].wgt+=p[to].wgt;
     55         if(maxs<p[to].wgt)
     56         {
     57             maxs=p[to].wgt;
     58             p[x].mxs=to;
     59         }
     60     }
     61     if(!p[x].mxs)
     62         p[x].sigf=0x3f3f3f3f;
     63     p[x].f=std::min(p[x].val,p[x].sigf);
     64     return ;
     65 }
     66 void Build_dfs(int x,int top)
     67 {
     68     if(!x)
     69         return ;
     70     p[x].tp=top;
     71     p[x].ind=++dfn;
     72     plc[dfn]=x;
     73     Build_dfs(p[x].mxs,top);
     74     for(int i=p[x].hd;i;i=e[i].lst)
     75     {
     76         int to=e[i].twd;
     77         if(p[to].ind)
     78             continue;
     79         Build_dfs(to,to);
     80     }
     81     return ; 
     82 }
     83 void pushup(int spc)
     84 {
     85     tr[spc].minv=std::min(tr[lll].minv,tr[rrr].minv);
     86     return ;
     87 }
     88 void add(int spc,lnt v)
     89 {
     90     tr[spc].lzt+=v;
     91     tr[spc].minv-=v;
     92     return ;
     93 }
     94 void pushdown(int spc)
     95 {
     96     if(tr[spc].lzt)
     97     {
     98         add(lll,tr[spc].lzt);
     99         add(rrr,tr[spc].lzt);
    100         tr[spc].lzt=0;
    101     }
    102     return ;
    103 }
    104 void build(int l,int r,int spc)
    105 {
    106     if(l==r)
    107     {
    108         tr[spc].minv=p[plc[l]].val-p[plc[l]].sigf;
    109         return ;
    110     }
    111     int mid=(l+r)>>1;
    112     build(l,mid,lll);
    113     build(mid+1,r,rrr);
    114     pushup(spc);
    115     return ;
    116 }
    117 void update(int l,int r,int pos,int spc,lnt v)
    118 {
    119     if(l==r)
    120     {
    121         add(spc,-v);
    122         return ;
    123     }
    124     int mid=(l+r)>>1;
    125     pushdown(spc);
    126     if(pos<=mid)
    127         update(l,mid,pos,lll,v);
    128     else
    129         update(mid+1,r,pos,rrr,v);
    130     pushup(spc);
    131     return ;
    132 }
    133 int scupdate(int l,int r,int ll,int rr,int spc,lnt v)
    134 {
    135     if(l>rr||ll>r)
    136         return 0;
    137     if(l==r)
    138     {
    139         add(spc,v);
    140         if(tr[spc].minv<=0)
    141             return plc[l];
    142         return 0;
    143     }
    144     if(ll<=l&&r<=rr&&tr[spc].minv>v)
    145     {
    146         add(spc,v);
    147         return 0;
    148     }
    149     int mid=(l+r)>>1;
    150     pushdown(spc);
    151     int plcc=scupdate(mid+1,r,ll,rr,rrr,v);
    152     if(!plcc)
    153         plcc=scupdate(l,mid,ll,rr,lll,v);
    154     pushup(spc);
    155     return plcc;
    156 }
    157 lnt query(int l,int r,int pos,int spc)
    158 {
    159     if(l==r)
    160         return tr[spc].minv;
    161     int mid=(l+r)>>1;
    162     pushdown(spc);
    163     if(pos<=mid)
    164         return query(l,mid,pos,lll);
    165     return query(mid+1,r,pos,rrr);
    166 }
    167 void Update(int x,lnt v)
    168 {
    169     if(v<=0||!x)
    170         return ;
    171     while(x)
    172     {
    173         int tp=scupdate(1,n,p[p[x].tp].ind,p[x].ind,1,v);
    174         if(!tp)
    175             x=p[p[x].tp].fa;
    176         else{
    177             Update(p[tp].fa,query(1,n,p[tp].ind,1)+v);
    178             return ;
    179         }
    180     }
    181 }
    182 int main()
    183 {
    184     scanf("%d",&n);
    185     for(int i=1;i<=n;i++)
    186         scanf("%d",&p[i].val);
    187     for(int i=1;i<n;i++)
    188     {
    189         int a,b;
    190         scanf("%d%d",&a,&b);
    191         ade(a,b);
    192         ade(b,a);
    193     }
    194     Basic_dfs(1,1);
    195     Build_dfs(1,1);
    196     build(1,n,1);
    197     scanf("%d",&m);
    198     while(m--)
    199     {
    200         scanf("%s",cmd+1);
    201         if(cmd[1]=='Q')
    202         {
    203             int x;
    204             scanf("%d",&x);
    205             printf("%lld
    ",std::min(p[x].val,p[x].val-query(1,n,p[x].ind,1)));
    206         }else{
    207             int x,v;
    208             scanf("%d%d",&x,&v);
    209             if(!v)
    210                 continue;
    211             p[x].val+=v;
    212             update(1,n,p[x].ind,1,v);
    213             lnt tmp=p[x].val-query(1,n,p[x].ind,1);
    214             p[x].f=std::min(p[x].val,tmp);
    215             Update(p[x].fa,p[x].f+v-p[x].val);
    216         }
    217     }    
    218     return 0;
    219 }
  • 相关阅读:
    解释机器学习模型的一些方法(一)——数据可视化
    机器学习模型解释工具-Lime
    Hive SQL 语法学习与实践
    LeetCode 198. 打家劫舍(House Robber)LeetCode 213. 打家劫舍 II(House Robber II)
    LeetCode 148. 排序链表(Sort List)
    LeetCode 18. 四数之和(4Sum)
    LeetCode 12. 整数转罗马数字(Integer to Roman)
    LeetCode 31. 下一个排列(Next Permutation)
    LeetCode 168. Excel表列名称(Excel Sheet Column Title)
    论FPGA建模,与面向对象编程的相似性
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10205803.html
Copyright © 2011-2022 走看看