kZjPBD.jpg

动态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\n",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 }

 

posted @ 2019-01-17 14:40  Through_The_Night  阅读(240)  评论(0编辑  收藏  举报