zoukankan      html  css  js  c++  java
  • BZOJ5210 最大连通子块和 【树链剖分】【堆】【动态DP】

    题目分析:

    解决了上次提到的《切树游戏》后,这道题就是一道模板题。

    注意我们需要用堆维护子重链的最大值。这样不会使得复杂度变坏,因为每个重链我们只考虑一个点。

    时间复杂度$O(nlog^2n)$

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef long long ll;
      5 
      6 const int maxn = 202000;
      7 
      8 int n,m;
      9 int v[maxn];
     10 vector<int> g[maxn];
     11 int fa[maxn],dep[maxn],sz[maxn],son[maxn],top[maxn],tail[maxn];
     12 int where[maxn],number[maxn],num;
     13 ll TOT[maxn];
     14 
     15 struct Priority_queue{
     16     priority_queue <ll,vector<ll>,less<ll> > pq,del;
     17     void Insert(ll now){pq.push(now);}
     18     void Erase(ll now){del.push(now);}
     19     ll Top(){
     20     while(!del.empty()&&pq.top() == del.top()) pq.pop(),del.pop();
     21     return pq.top();
     22     }
     23     int Size(){return pq.size()-del.size();}
     24 }PQ[maxn];
     25 
     26 struct node{ll L,R,D,C;}T[maxn<<2];
     27 
     28 void push_up(int now){
     29     T[now].L = max(T[now<<1].L,T[now<<1].C+T[now<<1|1].L);
     30     T[now].R = max(T[now<<1|1].R,T[now<<1|1].C+T[now<<1].R);
     31     T[now].D = max(max(T[now<<1].D,T[now<<1|1].D),T[now<<1].R+T[now<<1|1].L);
     32     T[now].C = T[now<<1].C+T[now<<1|1].C; 
     33 }
     34 
     35 node merge(node alpha,node beta){
     36     node gamma; gamma.L = max(alpha.L,alpha.C+beta.L);
     37     gamma.R = max(beta.R,beta.C+alpha.R);
     38     gamma.D = max(max(alpha.D,beta.D),alpha.R+beta.L);
     39     gamma.C = alpha.C+beta.C;
     40     return gamma;
     41 }
     42 
     43 char readchar(){
     44     char ch = getchar(); while(ch != 'M' && ch != 'Q') ch = getchar();
     45     return ch;
     46 }
     47 
     48 void read(){
     49     scanf("%d%d",&n,&m);
     50     for(int i=1;i<=n;i++) scanf("%d",&v[i]);
     51     for(int i=1;i<n;i++){
     52     int x,y; scanf("%d%d",&x,&y);
     53     g[x].push_back(y); g[y].push_back(x);
     54     }
     55 }
     56 
     57 void dfs1(int now,int f,int dp){
     58     fa[now] = f; dep[now] = dp;
     59     for(int i=0;i<g[now].size();i++){
     60     if(g[now][i] == f) continue;
     61     dfs1(g[now][i],now,dp+1);
     62     sz[now] += sz[g[now][i]];
     63     if(son[now]==0||sz[son[now]]<sz[g[now][i]])son[now]=g[now][i];
     64     }
     65     sz[now]++;
     66     if(son[now]) tail[now] = tail[son[now]];
     67     else tail[now] = now;
     68 }
     69 
     70 void dfs2(int now,int tp){
     71     top[now] = tp;number[now] = ++num; where[num] = now;
     72     if(son[now]) dfs2(son[now],tp);
     73     for(int i=0;i<g[now].size();i++){
     74     if(g[now][i] == fa[now] || g[now][i] == son[now]) continue;
     75     dfs2(g[now][i],g[now][i]);
     76     }
     77 }
     78 
     79 void Modify(int now,int tl,int tr,int place){
     80     if(tl == tr){
     81     tl = where[tl];
     82     T[now].C = TOT[tl] + v[tl];
     83     T[now].L = max(0ll,TOT[tl]+v[tl]); T[now].R = T[now].L;
     84     if(PQ[tl].Size()) T[now].D = max(PQ[tl].Top(),T[now].L);
     85     else T[now].D = T[now].L;
     86     }else{
     87     int mid = (tl+tr)/2;
     88     if(place <= mid) Modify(now<<1,tl,mid,place);
     89     else Modify(now<<1|1,mid+1,tr,place);
     90     push_up(now);
     91     }
     92 }
     93 
     94 node Query(int now,int tl,int tr,int l,int r){
     95     if(tl >= l && tr <= r) return T[now];
     96     int mid = (tl+tr)/2;
     97     if(r <= mid) return Query(now<<1,tl,mid,l,r);
     98     if(l > mid) return Query(now<<1|1,mid+1,tr,l,r);
     99     return merge(Query(now<<1,tl,mid,l,r),Query(now<<1|1,mid+1,tr,l,r));
    100 }
    101 
    102 void dfs3(int now){
    103     if(son[now]) dfs3(son[now]);
    104     for(int i=0;i<g[now].size();i++){
    105     int mp = g[now][i];
    106     if(mp == fa[now] || mp == son[now]) continue;
    107     dfs3(mp);
    108     PQ[now].Insert(Query(1,1,n,number[mp],number[tail[mp]]).D);
    109     }
    110     Modify(1,1,n,number[now]);
    111     if(top[now] == now){
    112     long long data = Query(1,1,n,number[now],number[tail[now]]).L;
    113     if(data > 0 && fa[now]) TOT[fa[now]]+=data; 
    114     }
    115 }
    116 
    117 void work(){
    118     dfs1(1,0,1);
    119     dfs2(1,1);
    120     dfs3(1);
    121     for(int i=1;i<=m;i++){
    122     char ch = readchar();
    123     if(ch == 'M'){
    124         int x,y; scanf("%d%d",&x,&y);
    125         stack<int> sta; int now = top[x];
    126         while(fa[now]) sta.push(now),now = top[fa[now]];
    127         while(!sta.empty()){
    128         int mp = sta.top();sta.pop();
    129         node res = Query(1,1,n,number[mp],number[tail[mp]]);
    130         PQ[fa[mp]].Erase(res.D);
    131         if(res.L > 0) TOT[fa[mp]]-=res.L;
    132         Modify(1,1,n,number[fa[mp]]);
    133         }
    134         now = x; v[x] = y;
    135         while(now){
    136         Modify(1,1,n,number[now]);
    137         now = top[now];
    138         node res = Query(1,1,n,number[now],number[tail[now]]);
    139         if(res.L > 0 && fa[now]) TOT[fa[now]]+=res.L;
    140         PQ[fa[now]].Insert(res.D);
    141         now= fa[now];
    142         }
    143     }else{
    144         int x; scanf("%d",&x);
    145         long long ans = Query(1,1,n,number[x],number[tail[x]]).D;
    146         printf("%lld
    ",ans);
    147     }
    148     }
    149 }
    150 
    151 int main(){
    152     read();
    153     work();
    154     return 0;
    155 }
  • 相关阅读:
    作业信息获取
    SQL Server数据库性能监控计数器
    c# 索引器學習
    C# DataGridView 小技巧
    C# DataTable 小技巧
    c# 小技巧
    C# new,Virtual,abstract,sealed,Override的簡單理解
    C# 位操作符
    C# 類型小技巧
    C# partial 局部类型
  • 原文地址:https://www.cnblogs.com/Menhera/p/9163493.html
Copyright © 2011-2022 走看看