动态dp 10pts WA求调
  • 板块P6021 洪水
  • 楼主ben090302
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/30 11:19
  • 上次更新2024/10/30 16:37:57
查看原帖
动态dp 10pts WA求调
609092
ben090302楼主2024/10/30 11:19
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=200005;
const int inf=0x3f3f3f3f3f3f3f;
struct edge{
    int v,nxt;
}e[N*2];
int n,m;
int hd[N],tot;
void add(int u,int v){
    e[++tot]={v,hd[u]},hd[u]=tot;
}
template<int R,int C>
struct matix{
    int r,c;
    int ele[R][C];
    matix():r(R),c(C){};
    void clear(){
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                ele[i][j]=inf;
            }
        }
    }
    int& operator()(int a,int b){
        return ele[a][b];
    }
};
template<int n,int m,int p>
auto operator*(matix<n,m> A,matix<m,p> B){
    matix<n,p> ret;
    ret.clear();
    for(int i=0;i<n;i++){
        for(int k=0;k<m;k++){
            for(int j=0;j<p;j++){
                ret(i,j)=min(ret(i,j),A(i,k)+B(k,j));
            }
        }
    }
    return ret;
}
matix<2,2> g[N],ident;

int val[N],f[N];
int dfn[N],nfd[N],top[N],edd[N],dep[N],fa[N],siz[N],son[N];
void dfs1(int u,int f){
    fa[u]=f,dep[u]=dep[f]+1;
    siz[u]=1;
    for(int i=hd[u];i;i=e[i].nxt){
        int v=e[i].v;
        if(v!=f){
            dfs1(v,u);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]]) son[u]=v;
        }
    }
}
int idx;
void dfs2(int u,int tp){
    top[u]=tp;
    dfn[u]=++idx;
    nfd[idx]=u;
    if(!son[u]){
        f[u]=val[u];
        g[u]=ident;
        edd[u]=u;
        return;
    }
    g[u](0,1)=val[u];
    dfs2(son[u],tp);
    edd[u]=edd[son[u]];
    for(int i=hd[u];i;i=e[i].nxt){
        int v=e[i].v;
        if(v!=son[u] and v!=fa[u]){
            dfs2(v,v);
            g[u](0,0)+=f[v];
        }
    }
    f[u]=min(val[u],g[u](0,0)+f[son[u]]);
}

matix<2,2> V[N*4];
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define mid ((l+r)>>1)
#define pushup(x) (V[x]=V[ls(x)]*V[rs(x)])
void build(int rt,int l,int r){
    if(l==r){
        V[rt]=g[nfd[l]];
        return;
    }
    build(ls(rt),l,mid);
    build(rs(rt),mid+1,r);
    pushup(rt);
} 
auto query(int rt,int l,int r,int L,int R){
    if(l>R or L>r) return ident;
    if(L<=l and r<=R) return V[rt];
    return query(ls(rt),l,mid,L,R)*query(rs(rt),mid+1,r,L,R);
}
void modi(int rt,int l,int r,int pos,int k){//pos点改为g[k]
    if(l==r){
        V[rt]=g[k];
        return;
    }
    if(pos<=mid) modi(ls(rt),l,mid,pos,k);
    else modi(rs(rt),mid+1,r,pos,k);
    pushup(rt);
}
auto queryt(int x){
    matix<2,1> tmp;
    tmp(0,0)=val[edd[x]],tmp(1,0)=0;
    return query(1,1,n,dfn[x],dfn[edd[x]])*tmp;
}
void modit(int x,int z){
    matix<2,1> nw,od;
    g[x](0,1)+=z;
    val[x]+=z;
    while(x){
        od=queryt(top[x]);
        modi(1,1,n,dfn[x],x);
        nw=queryt(top[x]);
        x=fa[top[x]];
        g[x](0,0)+=nw(0,0)-od(0,0);
    }
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    ident(1,0)=ident(0,1)=inf;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>val[i];
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
     
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    cin>>m;
    while(m--){
        char c;
        int x,k;
        cin>>c;
        if(c=='Q'){
            cin>>x;
            cout<<queryt(x)(0,0)<<"\n";
        }
        else{cin>>x>>k;modit(x,k);}
    }
}
2024/10/30 11:19
加载中...