动态dp入门(ddp)
大佬博客(矩阵有点问题)
大致就是写个树剖,弄个矩阵乱搞搞(满足转移)
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1e5+5; int n,m,hd[maxn],p[maxn]; struct node{int to,nt;}e[maxn<<1]; int k; inline void add(int x,int y){ e[++k].to=y;e[k].nt=hd[x];hd[x]=k; e[++k].to=x;e[k].nt=hd[y];hd[y]=k; } int siz[maxn],dep[maxn],top[maxn],seg[maxn],son[maxn],fa[maxn]; inline void dfs1(int x) { dep[x]=dep[fa[x]]+(siz[x]=1); for(int i=hd[x];i;i=e[i].nt){ int v=e[i].to;if(v==fa[x])continue; fa[v]=x;dfs1(v);siz[x]+=siz[v]; if(siz[v]>siz[son[x]])son[x]=v; } } int tot,rev[maxn],bot[maxn]; inline void dfs2(int x,int fp) { top[x]=fp;seg[x]=++tot;rev[tot]=x; if(son[x]) { dfs2(son[x],fp); bot[x]=bot[son[x]]; for(int i=hd[x];i;i=e[i].nt) if(!top[e[i].to])dfs2(e[i].to,e[i].to); } else bot[x]=x; } #define ll long long ll f[maxn][2]; inline void dp(int x) { f[x][1]=p[x];f[x][0]=0; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to;if(v==fa[x])continue; dp(v); f[x][1]+=f[v][0]; f[x][0]+=max(f[v][1],f[v][0]); } } //---------------------------------- struct Matrix { ll s[2][2]; inline Matrix operator*(Matrix a)const { Matrix ret; ret.s[0][0]=max(s[0][0]+a.s[0][0],s[0][1]+a.s[1][0]); ret.s[0][1]=max(s[0][0]+a.s[0][1],s[0][1]+a.s[1][1]); ret.s[1][0]=max(s[1][0]+a.s[0][0],s[1][1]+a.s[1][0]); ret.s[1][1]=max(s[1][0]+a.s[0][1],s[1][1]+a.s[1][1]); re ret; } }t[maxn<<2],tmp[maxn]; const ll inf=2147483647; #define ls rt<<1 #define rs rt<<1|1 inline void build(int rt,int l,int r) { if(l==r) { int x=rev[l],v; ll g0=f[x][0]-max(f[son[x]][1],f[son[x]][0]),g1=f[x][1]-f[son[x]][0]; /* for(int i=hd[x];i;i=e[i].nt) if((v=e[i].to)!=fa[x]&&v!=son[x]) { g0+=max(f[v][0],f[v][1]); g1+=f[v][0]; }*/ tmp[l]=t[rt]=(Matrix){{g0,g0,g1,-inf}}; re ; } int mid=(l+r)>>1; build(ls,l,mid);build(rs,mid+1,r); t[rt]=t[ls]*t[rs]; } inline void Modify(int rt,int l,int r,int pos) { if(l==r) { t[rt]=tmp[l]; re ; } int mid=(l+r)>>1; if(pos<=mid)Modify(ls,l,mid,pos); else Modify(rs,mid+1,r,pos); t[rt]=t[ls]*t[rs]; } inline Matrix query(int rt,int l,int r,int x,int y) { if(x<=l&&r<=y)re t[rt]; int mid=(l+r)>>1; if(y<=mid)re query(ls,l,mid,x,y); else if(x>mid)re query(rs,mid+1,r,x,y); else re query(ls,l,mid,x,y)*query(rs,mid+1,r,x,y); } inline Matrix Get_mat(int x){re query(1,1,n,seg[top[x]],seg[bot[x]]);} inline void modify(int x,int y) { tmp[seg[x]].s[1][0]+=(y-p[x]);p[x]=y; while(x) { Matrix a=Get_mat(x);Modify(1,1,n,seg[x]); Matrix b=Get_mat(x); x=fa[top[x]]; if(!x)re; tmp[seg[x]].s[0][1]=(tmp[seg[x]].s[0][0]+=max(b.s[0][0],b.s[1][0])-max(a.s[0][0],a.s[1][0])); tmp[seg[x]].s[1][0]+=b.s[0][0]-a.s[0][0]; } } int main() { // freopen("in.txt","r",stdin); rd(n),rd(m); int x,y; inc(i,1,n)rd(p[i]); inc(i,2,n) { rd(x),rd(y); add(x,y); } dfs1(1);dfs2(1,1);dp(1);build(1,1,n); inc(i,1,m) { rd(x),rd(y); modify(x,y); Matrix ans=Get_mat(1); printf("%lld\n",max(ans.s[0][0],ans.s[1][0])); } re 0; }