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\n"); 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\n",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; }