zoukankan      html  css  js  c++  java
  • 动态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
    ",max(ans.s[0][0],ans.s[1][0]));
        }
        re 0;
    }
  • 相关阅读:
    网络中有三种通讯模式:单播、广播、组播(多播)
    chmod命令
    linux bash 命令重定向和多命令执行
    linux中管道符“|”的作用
    web测试常用的 linux 命令
    集群主要分成三大类 (高可用集群, 负载均衡集群,科学计算集群)
    iOS 监测电话呼入
    iOS NSUserDefaults [setValue:forKey:] [setObject:forKey:] <Objc> setValue(_,forKey:) set(_,forKey) <Swift 3>
    iOS 将navigationItem.titleView设置为自定义UISearchBar (Ficow实例讲解)
    iOS 加载Viewcontroller的几种方法
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11760429.html
Copyright © 2011-2022 走看看