• 动态dp模板题(树剖+dp+线段树)


    动态最大带权独立集

    (还有一个是全局平衡二叉树的解法,还没学)


      1 #include"bits/stdc++.h"
      2 
      3 using namespace std;
      4 const int inf = 1e8;
      5 int n,m;
      6 int v[100005];
      7 const int nn = 1e5+10;
      8 
      9 int link[nn<<1],son[nn<<1],nxt[nn<<1];
     10 int tot_;
     11 int top[nn],deep[nn],wson[nn],fa[nn],size[nn],bot[nn];
     12 int f[nn][2];
     13 int dfn[nn];
     14 int id[nn];
     15 int tot;
     16 
     17 
     18 struct Mat
     19 {
     20    int l,r,a[3][3];
     21    Mat(int a1=0,int a2=0,int d1=0,int d2=0,int d3=0,int d4=0)
     22    {
     23       l=a1,r=a2;
     24       a[1][1]=d1,a[1][2] = d2;
     25       a[2][1] = d3,a[2][2] = d4;
     26    }
     27 
     28 
     29 }tr[nn<<2];
     30 
     31 Mat operator*(const Mat a,const Mat b)
     32 {
     33     Mat re=Mat(2,2);
     34 
     35 
     36     re.a[1][1] = max(a.a[1][1]+b.a[1][1],a.a[1][2]+b.a[2][1]);
     37      re.a[1][2] = max(a.a[1][1]+b.a[1][2],a.a[1][2]+b.a[2][2]);
     38 
     39       re.a[2][1] = max(a.a[2][1]+b.a[1][1],a.a[2][2]+b.a[2][1]);
     40        re.a[2][2] = max(a.a[2][1]+b.a[1][2],a.a[2][2]+b.a[2][2]); // 手动
     41 
     42    return re;
     43 }
     44 
     45 inline int rd(){
     46     int x=0;char c=getchar();int neg=1;
     47     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     48     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     49     return x*neg;
     50 }
     51 
     52 inline void adde(int x,int y)
     53 {
     54   ++tot_;
     55   nxt[tot_] = link[x];
     56   link[x] = tot_;
     57   son[tot_] = y;
     58 }
     59 
     60 void dfs1(int x,int ff,int dd)
     61 {
     62   fa[x] =ff;
     63   size[x] =1;
     64   f[x][1] = v[x];
     65   f[x][0] = 0;
     66 
     67   for (int i=link[x];i;i=nxt[i])
     68   {
     69      int so = son[i];
     70      if (so==ff) continue;
     71      dfs1(so,x,dd+1);
     72      size[x] += size[so];
     73      if (size[wson[x]]<size[so]) wson[x] = so;
     74      f[x][1] += f[so][0];
     75      f[x][0] += max(f[so][1],f[so][0]);
     76 
     77 
     78   }
     79 
     80 }
     81 
     82 void dfs2(int x,int t)
     83 {
     84    top[x] = t;
     85    dfn[x] = ++tot;
     86    id[tot] =x;
     87 
     88    if (!wson[x]) bot[top[x]] = x;//不要写成t
     89    else dfs2(wson[x],t);
     90 
     91    for ( int i=link[x];i;i=nxt[i])
     92    {
     93       int so =son[i];
     94       if (so==wson[x]||so==fa[x]) continue;
     95       dfs2(so,so);
     96    }
     97 }
     98 
     99 
    100 inline void change(int rt,int l,int r,int pos,int a,int b)
    101 {
    102   if (l==r)
    103   {
    104      tr[rt].a[1][1]+=a; tr[rt].a[2][1]+=a;
    105      tr[rt].a[1][2]+=b;
    106      return ;
    107   }
    108 
    109   int mid = l+r>>1;
    110   if (pos<=mid) change(rt<<1,l,mid,pos,a,b);
    111   else change(rt<<1|1,mid+1,r,pos,a,b);
    112   tr[rt]=tr[rt<<1|1]*tr[rt<<1];//注意顺序
    113 }
    114 
    115 
    116 inline Mat query(int p,int l,int r,int x,int y){
    117     if(x<=l&&r<=y)
    118     {
    119     return tr[p];
    120     }
    121     else{
    122         int m=l+r>>1;Mat re=Mat(2,2,0,-inf,-inf,0);
    123         if(y>=m+1) re=re*query(p<<1|1,m+1,r,x,y);
    124         if(x<=m) re=re*query(p<<1,l,m,x,y);
    125         return re;
    126     }
    127 }
    128 
    129 
    130 inline void update(int x,int y)
    131 {
    132    Mat nw,od;
    133  int a,b;
    134  while (x)
    135  { if (y) a=0,b=y,y=0;
    136   else a=max(nw.a[1][2],nw.a[1][1]) - max(od.a[1][2],od.a[1][1]),
    137   b = nw.a[1][1] - od.a[1][1];
    138 
    139   od = query(1,1,n,dfn[top[x]],dfn[bot[top[x]]]);
    140   change(1,1,n,dfn[x],a,b);
    141   nw = query(1,1,n,dfn[top[x]],dfn[bot[top[x]]]);
    142   x=fa[top[x]];
    143   }
    144 
    145   printf("%d
    ",max(nw.a[1][1],nw.a[1][2]));
    146 }
    147 
    148 void build (int rt,int l,int r)
    149 {
    150   if (l==r)
    151   {
    152      int zhi = id[l];
    153      int a = f[zhi][0] - max(f[wson[zhi]][0],f[wson[zhi]][1]);
    154      int b = f[zhi][1] - f[wson[zhi]][0];
    155      tr[rt] = Mat(2,2,a,b,a,-1e8);
    156      return ;
    157   }
    158 
    159   int mid = l+r>>1;
    160   build(rt<<1,l,mid);
    161   build(rt<<1|1,mid+1,r);
    162   tr[rt]=tr[rt<<1|1]*tr[rt<<1];
    163 }
    164 
    165 int main()
    166 {
    167   n=rd(); m = rd();
    168   for ( int i=1;i<=n;i++) v[i] = rd();
    169 
    170   for ( int i =1;i<n;i++)
    171   {
    172      int a,b;a=rd(); b = rd();
    173      adde(a,b);
    174      adde(b,a);
    175   }
    176   dfs1(1,0,1);
    177   dfs2(1,1);
    178 
    179   build(1,1,n);
    180   //puts("$%^&*");
    181 
    182   for ( int i=1;i<=m;i++)
    183 
    184   {
    185    //  puts("123f");
    186      int a,b;a=rd();  b=rd();
    187 
    188      update(a,b-v[a]);
    189    //  puts("213");
    190      v[a] =b;
    191   }
    192   return 0;
    193 }
  • 相关阅读:
    Xcode 10 storyBoard中控件区域位置修改
    使用WeexSDK,网络请求信任证书的问题
    真机调试包,解决xcode跑不了高版本iOS系统问题,及Deployment Target不显示高版本系统的问题
    vim进阶学习
    Linux中的inode(转载)
    Linux的文件权限
    远程连接Linux服务器
    WinSDK绘制文本
    (转载)Win32 SDK编程系列文章——菜单(快捷菜单)——动态加载
    (转载)Windows Socket五种I/O模型——代码全攻略
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10282131.html
Copyright © 2020-2023  润新知