保卫王国

洛谷

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

#define int long long
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],son[maxn],fa[maxn];
inline void dfs1(int 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,seg[maxn],rev[maxn],top[maxn],bot[maxn];
inline void dfs2(int x,int fp)
{
    seg[x]=++tot;rev[tot]=x;
    top[x]=fp; 
    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;
}
int 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(e[i].to==fa[x])continue;
        dp(v);
        f[x][1]+=min(f[v][0],f[v][1]);
        f[x][0]+=f[v][1];
    }
}

//-------------------------
struct Matrix{
    int s[2][2];
    inline Matrix operator*(Matrix a)const 
    {
        Matrix ret;
        ret.s[0][0]=min(s[0][0]+a.s[0][0],s[0][1]+a.s[1][0]); 
        ret.s[0][1]=min(s[0][0]+a.s[0][1],s[0][1]+a.s[1][1]); 
        ret.s[1][0]=min(s[1][0]+a.s[0][0],s[1][1]+a.s[1][0]); 
        ret.s[1][1]=min(s[1][0]+a.s[0][1],s[1][1]+a.s[1][1]); 
        re ret;
    }
}t[maxn<<2],tmp[maxn],be[maxn];
const int 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];
        int g1=f[x][1]-min(f[son[x]][0],f[son[x]][1]),g0=f[x][0]-f[son[x]][1];
        be[l]=tmp[l]=t[rt]=(Matrix){g1,g1,g0,inf};
        re ;
    }
    
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    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);
    re query(ls,l,mid,x,y)*query(rs,mid+1,r,x,y);
}

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 Get_mat(int x){re query(1,1,n,seg[top[x]],seg[bot[x]]);}

inline void modify(int x,int y)
{
    if(y)tmp[seg[x]].s[0][0]=tmp[seg[x]].s[0][1]=inf;
    else tmp[seg[x]].s[1][0]=inf;
    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]+=min(b.s[1][0],b.s[0][0])-min(a.s[1][0],a.s[0][0]));
         tmp[seg[x]].s[1][0]+=b.s[0][0]-a.s[0][0];
    }
}

inline void rebuild(int x)
{
    while(x)
    {
        tmp[seg[x]]=be[seg[x]];
        Modify(1,1,n,seg[x]);
        x=fa[top[x]];
    }
}
#undef int
int main()
{
    #define int long long
//    freopen("in.txt","r",stdin);
    int x,y;
    char TY[4];
    rd(n),rd(m);
    scanf("%s",TY);
    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);
    
    int a,b;
    inc(i,1,m)
    {
        rd(a),rd(x),rd(b),rd(y);
        x^=1;y^=1;
        if(x&&y&&(fa[a]==b||fa[b]==a))puts("-1");
        else
        {
            modify(a,x);modify(b,y);
            Matrix ans=Get_mat(1);
            int now=min(ans.s[1][0],ans.s[0][0]);
            printf("%lld\n",now); 
            rebuild(a);rebuild(b);        
        }
    }
    re 0;
} 

 

posted @ 2019-10-29 17:54  凉如水  阅读(243)  评论(0编辑  收藏  举报