动态DP学习笔记

动态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\n",max(ans.a[0][0],ans.a[1][0]));
    }
    return 0;
}

posted @ 2019-01-01 21:22  饕餮传奇  阅读(400)  评论(1编辑  收藏  举报