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; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/10968136.html