luoguP4719 【模板】动态 DP 线段树_树链剖分_矩阵乘法_动态DP
作者:互联网
Code:
#include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 300000 #define lson (now<<1) #define rson ((now<<1)|1) #define ll long long const ll inf = 1e17; using namespace std; int hd[maxn],to[maxn],nex[maxn],V[maxn],hson[maxn],fa[maxn],dfn[maxn], ln[maxn],F[maxn][2],siz[maxn],top[maxn],bot[maxn]; int edges,tim,n,Q; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs1(int u,int ff) { siz[u]=1,fa[u]=ff; for(int i=hd[u];i;i=nex[i]) { if(to[i]==ff) continue; dfs1(to[i],u); siz[u]+=siz[to[i]]; if(siz[to[i]] > siz[hson[u]]) hson[u]=to[i]; } } void dfs2(int u,int tp) { top[u]=tp,ln[++tim]=u,dfn[u]=tim; if(hson[u]) dfs2(hson[u], tp), bot[u]=bot[hson[u]]; else bot[u]=u; for(int i=hd[u];i;i=nex[i]) { if(to[i]==fa[u]||to[i]==hson[u]) continue; dfs2(to[i],to[i]); } } void dfs(int u) { F[u][0]=0,F[u][1]=V[u]; for(int i=hd[u];i;i=nex[i]) { if(to[i]==fa[u]) continue; dfs(to[i]); F[u][0]+=max(F[to[i]][1],F[to[i]][0]); F[u][1]+=F[to[i]][0]; } } struct Matrix { ll a[2][2]; ll*operator[](int x){ return a[x]; } }t[maxn<<1],tmp[maxn<<1]; Matrix operator*(Matrix a,Matrix b) { Matrix c; c[0][0]=max(a[0][0]+b[0][0],a[0][1]+b[1][0]); c[0][1]=max(a[0][0]+b[0][1],a[0][1]+b[1][1]); c[1][0]=max(a[1][0]+b[0][0],a[1][1]+b[1][0]); c[1][1]=max(a[1][0]+b[0][1],a[1][1]+b[1][1]); return c; } void Build(int now,int l,int r) { if(l==r) { int u=ln[l]; ll g0=0,g1=V[u]; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==fa[u]||v==hson[u]) continue; g0+=max(F[v][0],F[v][1]); g1+=F[v][0]; } t[now]=tmp[l]=(Matrix) {g0,g0,g1,-inf}; return; } int mid=(l+r)>>1; Build(lson,l,mid),Build(rson,mid+1,r); t[now]=t[lson]*t[rson]; } void Modify(int now,int l,int r,int p) { if(l==r) { t[now]=tmp[l]; return; } int mid=(l+r)>>1; if(p<=mid) Modify(lson,l,mid,p); else Modify(rson,mid+1,r,p); t[now]=t[lson]*t[rson]; } Matrix Query(int now,int l,int r,int L,int R) { if(L==l&&r==R) return t[now]; int mid=(l+r)>>1; if(R<=mid) return Query(lson,l,mid,L,R); if(L>mid) return Query(rson,mid+1,r,L,R); return Query(lson,l,mid,L,mid)*Query(rson,mid+1,r,mid+1,R); } void Update(int u,int w) { tmp[dfn[u]][1][0]+=w-V[u],V[u]=w; while(u) { Matrix a=Query(1,1,n,dfn[top[u]],dfn[bot[u]]); Modify(1,1,n,dfn[u]); Matrix b=Query(1,1,n,dfn[top[u]],dfn[bot[u]]); u=fa[top[u]]; if(!u) break; int x = dfn[u]; ll g0=a[0][0],g1=a[1][0],f0=b[0][0],f1=b[1][0]; tmp[x][0][0]=tmp[x][0][1]=tmp[x][0][0]+max(f0,f1)-max(g0,g1); tmp[x][1][0]=tmp[x][1][0]+f0-g0; } } int main() { // setIO("input"); scanf("%d%d",&n,&Q); for(int i=1;i<=n;++i) scanf("%d",&V[i]); for(int i=1,u,v;i<n;++i) { scanf("%d%d",&u,&v),add(u,v),add(v,u); } dfs1(1,0),dfs2(1,1),dfs(1),Build(1,1,n); while(Q--) { int x,w; scanf("%d%d",&x,&w); Update(x,w); Matrix ans=Query(1,1,n,dfn[1],dfn[bot[1]]); printf("%lld\n",max(ans[0][0],ans[1][0])); } return 0; }
标签:tmp,hson,剖分,int,bot,mid,dfn,动态,DP 来源: https://www.cnblogs.com/guangheli/p/10965885.html