zoukankan      html  css  js  c++  java
  • bzoj 5210(树链刨分下做个dp)

    5210: 最大连通子块和

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 211  Solved: 65
    [Submit][Status][Discuss]

    Description

    给出一棵n个点、以1为根的有根树,点有点权。要求支持如下两种操作:
    M x y:将点x的点权改为y;
    Q x:求以x为根的子树的最大连通子块和。
    其中,一棵子树的最大连通子块和指的是:该子树所有子连通块的点权和中的最大值
    (本题中子连通块包括空连通块,点权和为0)。

    Input

    第一行两个整数n、m,表示树的点数以及操作的数目。
    第二行n个整数,第i个整数w_i表示第i个点的点权。
    接下来的n-1行,每行两个整数x、y,表示x和y之间有一条边相连。
    接下来的m行,每行输入一个操作,含义如题目所述。保证操作为M x y或Q x之一。
    1≤n,m≤200000 ,任意时刻 |w_i|≤10^9 。

    Output

    对于每个Q操作输出一行一个整数,表示询问子树的最大连通子块和。

    Sample Input

    5 4
    3 -2 0 3 -1
    1 2
    1 3
    4 2
    2 5
    Q 1
    M 4 1
    Q 1
    Q 2

    Sample Output

    4
    3
    1

    我不知道什么动态dp,我只知道这是一个数据结构题。每次写个树链刨分都得弄半天orz。
    大神题解:CQzhangyu
     
      1 #include<bits/stdc++.h>
      2 #define clr(x) memset(x,0,sizeof(x))
      3 #define clr_1(x) memset(x,-1,sizeof(x))
      4 #define INF 0x3f3f3f3f
      5 #define LL long long
      6 #define pb push_back
      7 #define ls(i) (i<<1)
      8 #define rs(i) (i<<1|1)
      9 #define mp make_pair
     10 #define fi first
     11 #define se second
     12 using namespace std;
     13 const int N=2e5+10;
     14 int tsize[N];
     15 int son[N],down[N],top[N],dep[N],pos[N],pot[N],fat[N];
     16 int tot;
     17 int n,q;
     18 LL v[N],f[N],g[N],maxs[N];
     19 vector<int> e[N];
     20 struct heap
     21 {
     22     priority_queue<LL> ins,del;
     23     inline void push(LL x)
     24     {
     25         ins.push(x);
     26         return ;
     27     }
     28     inline void pop(LL x)
     29     {
     30         del.push(x);
     31         return ;
     32     }
     33     inline LL top()
     34     {
     35         while(!del.empty() && ins.top()==del.top())
     36             ins.pop(),del.pop();
     37         if(ins.empty()) return 0LL;
     38         return ins.top();
     39     }
     40     void pop()
     41     {
     42         top();
     43         del.push(ins.top());
     44         return ;
     45     }
     46 }lsq[N];
     47 void dfs1(int u,int d,int fa)
     48 {
     49 //    cout<<"begin:"<<u<<" "<<son[u]<<endl;
     50     dep[u]=d;
     51     tsize[u]=1;
     52     fat[u]=fa;
     53     int sz=e[u].size(),p;
     54     for(int i=0;i<sz;i++)
     55     {
     56         p=e[u][i];
     57 //        cout<<"branch:"<<u<<" "<<p<<" "<<fa<<endl;
     58         if(p!=fa)
     59         {
     60             dfs1(p,d+1,u);
     61             tsize[u]+=tsize[p];
     62             if(!son[u] || tsize[p]>tsize[son[u]])
     63                 son[u]=p;
     64         }
     65     }
     66 //    cout<<"endn:"<<u<<" "<<son[u]<<endl;
     67     return ;
     68 }
     69 void dfs2(int u,int tp)
     70 {
     71 //    cout<<u<<endl;
     72     top[u]=tp;
     73     pos[u]=++tot;
     74     pot[tot]=u;
     75     if(son[u]) dfs2(son[u],tp),down[u]=down[son[u]],maxs[u]=maxs[son[u]];
     76     else down[u]=u,maxs[u]=0;
     77     int sz=e[u].size();
     78     g[u]=v[u];
     79     for(int i=0;i<sz;i++)
     80     {
     81         int p=e[u][i];
     82         if(p!=fat[u] && p!=son[u])
     83         {
     84             dfs2(p,p);
     85             g[u]+=f[p];
     86             lsq[u].push(maxs[p]);
     87         }
     88     }
     89     f[u]=max(0LL,g[u]+f[son[u]]),maxs[u]=max(maxs[u],f[u]),maxs[u]=max(maxs[u],lsq[u].top());
     90     return ;
     91 }
     92 struct segt
     93 {
     94     int l,r;
     95     LL all,maxl,maxr,maxn;
     96     segt operator + (const segt &b)
     97     {
     98         segt p;
     99         p.maxl=max(maxl,all+b.maxl);
    100         p.maxr=max(b.maxr,maxr+b.all);
    101         p.all=all+b.all;
    102         p.maxn=max(max(maxn,b.maxn),maxr+b.maxl);
    103         p.l=l;
    104         p.r=b.r;
    105         return p;
    106     }
    107 }seg[N<<2];
    108 void init(int i,int l,int r)
    109 {
    110     if(l==r)
    111     {
    112         int x=pot[l];
    113         seg[i]=(segt){l,r,g[x],max(0LL,g[x]),max(0LL,g[x]),max(g[x],lsq[x].top())};
    114         return ;
    115     }
    116     int mid=l+r>>1;
    117     init(i<<1,l,mid);
    118     init(i<<1|1,mid+1,r);
    119     seg[i]=seg[i<<1]+seg[i<<1|1];
    120     return ;
    121 }
    122 char s[10];
    123 void refresh(int i,int pos)
    124 {
    125     if(seg[i].l==seg[i].r)
    126     {
    127         int x=pot[seg[i].l];
    128         segt p=(segt){seg[i].l,seg[i].r,g[x],max(0LL,g[x]),max(0LL,g[x]),max(g[x],lsq[x].top())};
    129         seg[i]=p;
    130         return ;
    131     }
    132     int mid=seg[i].l+seg[i].r>>1;
    133     if(mid>=pos) refresh(i<<1,pos);
    134     else refresh(i<<1|1,pos);
    135 
    136     seg[i]=seg[i<<1]+seg[i<<1|1];
    137     return ;
    138 }
    139 segt query(int i,int l,int r)
    140 {
    141     if(seg[i].l>=l && seg[i].r<=r)    return seg[i];
    142     int mid=seg[i].l+seg[i].r>>1;
    143     if(r<=mid)   return query(i<<1,l,r);
    144     if(l>mid)    return query(i<<1|1,l,r);
    145     return query(i<<1,l,r)+query(i<<1|1,l,r);
    146 }
    147 void update(int u,LL val)
    148 {
    149     segt t1,t2,t3;
    150     bool flag=0;
    151 //    cout<<u<<endl;
    152     while(u)
    153     {
    154 //        cout<<u<<endl;
    155         t3=query(1,pos[top[u]],pos[down[u]]);
    156         if(flag)    lsq[u].pop(t1.maxn),lsq[u].push(t2.maxn);
    157         t1=t3;
    158         flag=1;
    159         g[u]+=val,refresh(1,pos[u]);
    160         t2=query(1,pos[top[u]],pos[down[u]]);
    161         val=t2.maxl-f[top[u]],f[top[u]]=t2.maxl;
    162         u=fat[top[u]];
    163     }
    164     return ;
    165 }
    166 int main()
    167 {
    168     tot=0;
    169     scanf("%d%d",&n,&q);
    170     for(int i=1;i<=n;i++)
    171         scanf("%lld",v+i);
    172     for(int i=2;i<=n;i++)
    173     {
    174         int u,v;
    175         scanf("%d%d",&u,&v);
    176         e[u].pb(v);
    177         e[v].pb(u);
    178     }
    179     dfs1(1,1,0);
    180     dfs2(1,1);
    181     init(1,1,n);
    182     for(int i=1;i<=q;i++)
    183     {
    184         scanf("%s",s);
    185         if(s[0]=='M')
    186         {
    187             int u;
    188             LL num;
    189             scanf("%d%lld",&u,&num);
    190             update(u,num-v[u]);
    191             v[u]=num;
    192         }
    193         else
    194         {
    195             int u;
    196             scanf("%d",&u);
    197             printf("%lld
    ",query(1,pos[u],pos[down[u]]).maxn);
    198         }
    199     }
    200     return 0;
    201 }
    View Code
  • 相关阅读:
    js面试相关
    邮件(一):Springboot+thymeleaf的发邮件部分
    饿了么组件--table组件自定义渲染列,同时伴有v-for和v-if情况
    java开发规范学习
    java发送邮件
    vue垂死挣扎--遇到的问题
    vue学习记录
    matlab---设置背景颜色为白色
    Git push时不需要总输入密码
    我不知道的js(一)作用域与闭包
  • 原文地址:https://www.cnblogs.com/wujiechao/p/9231578.html
Copyright © 2011-2022 走看看