zoukankan      html  css  js  c++  java
  • BZOJ 5466: [Noip2018]保卫王国 动态DP

    Code:

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define ll long long  
    #define lson (now<<1) 
    #define rson ((now<<1)|1)      
    #define setIO(s) freopen(s".in","r",stdin) 
    #define maxn 300000 
    const long long inf = 100000000000000; 
    using namespace std;
    char uuu[9];  
    ll V[maxn]; 
    int fa[maxn],hd[maxn],to[maxn],nex[maxn],siz[maxn],hson[maxn]; 
    int F[maxn][2];  
    int top[maxn],bot[maxn],dfn[maxn],ln[maxn];
    int edges,tim,n,Q;  
    void add(int u,int v)
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
    }
    struct Matrix
    {
        ll a[2][2]; 
        ll*operator[](int x){return a[x]; }
    }t[maxn<<1],tmp[maxn]; 
    Matrix operator*(Matrix a,Matrix b)
    {
        Matrix c;
        c[0][0]=min(a[0][0]+b[0][0],a[0][1]+b[1][0]); 
        c[0][1]=min(a[0][0]+b[0][1],a[0][1]+b[1][1]); 
        c[1][0]=min(a[1][0]+b[0][0],a[1][1]+b[1][0]); 
        c[1][1]=min(a[1][0]+b[0][1],a[1][1]+b[1][1]); 
        return c; 
    }
    void dfs1(int u,int ff)
    {
        fa[u]=ff,siz[u]=1;
        for(int i=hd[u];i;i=nex[i])
        {
            int v=to[i];
            if(v==ff) continue; 
            dfs1(v,u); 
            siz[u]+=siz[v];
            if(siz[v]>siz[hson[u]]) hson[u]=v; 
        }
    }
    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])
        {
            int v=to[i]; 
            if(v==fa[u]||v==hson[u]) continue; 
            dfs2(v,v); 
        }
    }
    void dfs(int u)
    {
        F[u][0]=0,F[u][1]=V[u]; 
        for(int i=hd[u];i;i=nex[i])
        {
            int v=to[i];
            if(v==fa[u]) continue; 
            dfs(v); 
            F[u][0]+=F[v][1];
            F[u][1]+=min(F[v][0],F[v][1]);       
        }
    }
    void build(int l,int r,int now)
    {
        if(l>r) return; 
        if(l==r)
        {
            int u=ln[l]; 
            ll f0=0,f1=V[u]; 
            for(int i=hd[u];i;i=nex[i])
            {
                int v=to[i];
                if(v==fa[u]||v==hson[u]) continue; 
                f0+=F[v][1];
                f1+=min(F[v][0],F[v][1]);      
            }
            t[now]=tmp[l]=(Matrix){inf, f0,f1,f1}; 
            return; 
        }
        int mid=(l+r)>>1; 
        build(l,mid,lson),build(mid+1,r,rson); 
        t[now]=t[lson]*t[rson]; 
    }
    void modify(int l,int r,int now,int p)
    {
        if(l==r)
        {
            t[now]=tmp[l];
            return; 
        }
        int mid=(l+r)>>1;
        if(p<=mid) 
            modify(l,mid,lson,p);
        else 
            modify(mid+1,r,rson,p); 
        t[now]=t[lson]*t[rson]; 
    }
    Matrix query(int l,int r,int now,int L,int R)
    {
        if(l==L&&r==R) return t[now];
        int mid=(l+r)>>1;
        if(R<=mid) return query(l,mid,lson,L,R); 
        if(L>mid) return query(mid+1,r,rson,L,R); 
        return query(l,mid,lson,L,mid)*query(mid+1,r,rson,mid+1,R); 
    }
    void Update(int u,ll w)
    {
        tmp[dfn[u]][1][0]=tmp[dfn[u]][1][1]+=w-V[u], V[u]=w;   
        while(u)
        {
            Matrix a=query(1,n,1,dfn[top[u]],dfn[bot[u]]); 
            modify(1,n,1,dfn[u]); 		
            Matrix b=query(1,n,1,dfn[top[u]],dfn[bot[u]]); 
            u=fa[top[u]]; 
            if(!u) return;
            int x=dfn[u]; 
            ll f0=a[0][1],f1=a[1][1],g0=b[0][1],g1=b[1][1]; 
            tmp[x][1][0]=tmp[x][1][1]=tmp[x][1][0]+min(g1,g0)-min(f1,f0); 
            tmp[x][0][1]=tmp[x][0][1]+g1-f1;  
        }
    }
    void solve(int a,int x,int b,int y)
    {
        if(!x&&!y&&(fa[a]==b||fa[b]==a)) { printf("-1
    "); return ;}  
        ll o=V[a],oo=V[b]; 
        Update(a,x?o-inf:o+inf), Update(b,y?oo-inf:oo+inf);  
        Matrix ans=query(1,n,1,dfn[top[1]],dfn[bot[1]]);  
        ll h=min(ans[0][1],ans[1][1]); 
        if(x) h+=inf; 
        if(y) h+=inf; 
        printf("%lld
    ",h); 
        Update(a,o), Update(b,oo); 
    }
    int main()
    {
        // setIO("input"); 
        scanf("%d%d%s",&n,&Q,uuu); 
        for(int i=1;i<=n;++i) scanf("%lld",&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,n,1); 
        while(Q--)
        {
        	int a,x,b,y; 
        	scanf("%d%d%d%d",&a,&x,&b,&y);             
        	solve(a,x,b,y); 
        }
        return 0; 
    }
    

      

  • 相关阅读:
    php工作笔记5-css定位
    php工作笔记4-mysql笔记1
    php工作笔记3-php基础加强
    php工作笔记2-php编码效率
    php工作笔记1-数组常用方法总结,二维数组的去重,上传图片到oss服务器
    android浏览器 源码共享
    违章查询源码分享
    CENTOS 6.5 配置YUM安装NGINX
    Linux下安装Oracle11g服务器
    ARCGIS SDE空间化处理
  • 原文地址:https://www.cnblogs.com/guangheli/p/10968136.html
Copyright © 2011-2022 走看看