动态DP学习笔记
Tags:动态规划
一、概述
最近博主学习了超多新科技
大概就是不能去WC然后只能用学习填补我可怜弱小又无助的心灵吧
从今天开时,大部分的学习笔记就真的是笔记了。。
各位如果图片看得不爽的话那就把这个当做博主存笔记的地方吧。。
毕竟博主是很喜欢用修正带的。。
二、题目
- 洛谷模板
- BZOJ 洪水
- Noip 保卫王国
- SDOI 切树游戏
三、模板的代码
// luogu-judger-enable-o2
#include<iostream>
using namespace std;
int read()
{
char ch=getchar();int h=0,t=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
return h*t;
}
const int N=1e5+10;
struct Matrix
{
int a[2][2];
Matrix () {a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;}
Matrix operator * (Matrix B) const
{
Matrix C;
C.a[0][0]=max(a[0][0]+B.a[0][0],a[0][1]+B.a[1][0]);
C.a[0][1]=max(a[0][0]+B.a[0][1],a[0][1]+B.a[1][1]);
C.a[1][0]=max(a[1][0]+B.a[0][0],a[1][1]+B.a[1][0]);
C.a[1][1]=max(a[1][0]+B.a[0][1],a[1][1]+B.a[1][1]);
return C;
}
}t[N<<2],val[N],ans;
struct edge{int next,to;}a[N<<1];
int n,m,f[N][2],id[N],dfn[N],top[N],fa[N],son[N];
int head[N],cnt,siz[N],tot,ed[N],v[N];
void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i;i=a[i].next)
{
int R=a[i].to;if(R==fa[x]) continue;
fa[R]=x;dfs1(R);siz[x]+=siz[R];
if(siz[R]>siz[son[x]]) son[x]=R;
}
}
void dfs2(int x)
{
dfn[x]=++tot;id[tot]=x;
top[x]=top[fa[x]];
if(son[fa[x]]!=x) top[x]=x;
if(son[x]) dfs2(son[x]);
else ed[top[x]]=tot;
for(int i=head[x];i;i=a[i].next)
if(a[i].to!=son[x]&&a[i].to!=fa[x]) dfs2(a[i].to);
}
void dfs(int x)
{
f[x][1]=max(0,v[x]);
for(int i=head[x];i;i=a[i].next)
{
int R=a[i].to;if(R==fa[x]) continue;
dfs(R);f[x][1]+=f[R][0];
f[x][0]+=max(f[R][0],f[R][1]);
}
}
void build(int now,int l,int r)
{
if(l==r)
{
t[now].a[0][0]=f[id[l]][0]-max(f[son[id[l]]][0],f[son[id[l]]][1]);
t[now].a[0][1]=t[now].a[0][0];
t[now].a[1][0]=f[id[l]][1]-f[son[id[l]]][0];
val[l]=t[now];return;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
t[now]=t[now<<1]*t[now<<1|1];
}
void modify(int now,int l,int r,int ps)
{
if(l==r) {t[now]=val[l];return;}
int mid=(l+r)>>1;
if(ps<=mid) modify(now<<1,l,mid,ps);
else modify(now<<1|1,mid+1,r,ps);
t[now]=t[now<<1]*t[now<<1|1];
}
Matrix Query(int now,int l,int r,int gl,int gr)
{
if(l>=gl&&r<=gr) return t[now];
int mid=(l+r)>>1;
if(gr<=mid) return Query(now<<1,l,mid,gl,gr);
if(gl>mid) return Query(now<<1|1,mid+1,r,gl,gr);
return Query(now<<1,l,mid,gl,gr)*
Query(now<<1|1,mid+1,r,gl,gr);
}
void work(int x,int w)
{
val[dfn[x]].a[1][0]+=max(w,0)-max(v[x],0);v[x]=w;
Matrix od,nw;
while(x)
{
od=Query(1,1,n,dfn[top[x]],ed[top[x]]);
modify(1,1,n,dfn[x]);
nw=Query(1,1,n,dfn[top[x]],ed[top[x]]);
x=fa[top[x]];
val[dfn[x]].a[0][0]+=max(nw.a[0][0],nw.a[1][0])-max(od.a[0][0],od.a[1][0]);
val[dfn[x]].a[0][1]=val[dfn[x]].a[0][0];
val[dfn[x]].a[1][0]+=nw.a[0][0]-od.a[0][0];
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) v[i]=read();
for(int i=1,x,y;i<n;i++) cin>>x>>y,link(x,y),link(y,x);
dfs1(1);dfs2(1);dfs(1);build(1,1,n);
for(int ii=1,x,y;ii<=m;ii++)
{
x=read();y=read();
work(x,y);ans=Query(1,1,n,1,ed[1]);
printf("%d
",max(ans.a[0][0],ans.a[1][0]));
}
return 0;
}