萌新求助简单树剖线段树dp题
查看原帖
萌新求助简单树剖线段树dp题
455490
Sharpsmile楼主2024/11/8 09:27

rt

无法通过样例的第二个包,好像不是多测的问题,单独拿出来也是错的。第7个NO判成了yes。

佬帮帮qwq

#include<bits/stdc++.h>
using namespace std;
#define int long long

// #define endl "\n"
#define pii pair<int,int>
#define p1(x) x.first
#define p2(x) x.second
// #pragma GCC optimize("Ofast")
const int MXN=200030;
int n,q;
inline void chkmin(int &x,int y){if(x>y)x=y;}
struct mat{
    int T[3][3];
    mat(bool p=0){
        memset(T,0x3f,sizeof(T));
        if(p)
        T[0][0]=T[1][1]=T[2][2]=0;
    }
    friend mat operator *(const mat A,const mat B){
        mat C(0);
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    chkmin(C.T[i][j],A.T[i][k]+B.T[k][j]);
        return C;
    }
}w[MXN<<2];
#define lc(x) x<<1
#define rc(x) x<<1|1
inline void upd(int x){
    w[x]=w[lc(x)]*w[rc(x)];
}
int h[MXN],g[MXN],s[MXN];
int tk,dfn[MXN],loc[MXN];
inline void rst(int x,int p){
    w[x]=mat(0);
    w[x].T[0][0]=min(g[p],h[p]);
    w[x].T[1][0]=w[x].T[1][1]=s[p];
    w[x].T[2][0]=h[p];
    w[x].T[2][2]=0;
}
inline void mod(int x,int l,int r,int c){
    if(l==r){
        rst(x,loc[l]);
        return ;
    }
    int mid=l+r>>1;
    if(c<=mid)mod(lc(x),l,mid,c);
    else mod(rc(x),mid+1,r,c);
    upd(x);
}
inline mat gt(int x,int l,int r,int L,int R){
    // cout<<l<<" "<<r<<" "<<L<<" "<<R<<endl;
    if(L<=l&&r<=R)return w[x];
    int mid=l+r>>1;
    mat res(1);
    if(L<=mid)res=res*gt(lc(x),l,mid,L,R);
    if(R>mid)res=res*gt(rc(x),mid+1,r,L,R);
    return res;
}
inline void bd(int x,int l,int r){
    if(l==r){
        rst(x,loc[l]);
        return ;
    }
    int mid=l+r>>1;
    bd(lc(x),l,mid),bd(rc(x),mid+1,r);
    upd(x);
}
int hs[MXN],tp[MXN],siz[MXN],fa[MXN],bot[MXN];
vector<int>gr[MXN];
int f[MXN],mf[MXN];
inline int dfs(int u,int t){
    // cout<<u<<" "<<t<<endl;
    tp[u]=t;
    bot[u]=u;
    loc[dfn[u]=tk--]=u;
    if(hs[u])bot[u]=dfs(hs[u],t);
    for(int v:gr[u])if(v!=hs[u])dfs(v,v);
    return bot[u];
}
mat st;
inline int F(int u){
    return (st*gt(1,1,n,dfn[bot[u]],dfn[u])).T[0][0];
}
inline void add(int x,int da,int dc){
    s[x]+=da-dc;
    g[x]+=da;
    h[x]+=da;
    mod(1,1,n,dfn[x]);
    while(x){
        x=tp[x];
        
        if(x==1)break;
        int y=fa[x];
        s[y]+=da-dc;
        g[y]+=da;
        h[y]+=da;
        // cout<<g[y]<<"x"<<f[x]<<" ";
        g[y]-=f[x];
        h[y]-=mf[x];
        
        f[x]=F(x);
        mf[x]=min(0ll,f[x]);
        
        g[y]+=f[x];
        h[y]+=mf[x];
        // cout<<g[y]<<"x"<<f[x]<<endl;
        mod(1,1,n,dfn[y]);
        x=fa[x];
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    freopen("genshin.in","r",stdin);
    freopen("genshin.out","w",stdout);
    int t;
    cin>>t;
    st.T[0][0]=st.T[0][1]=st.T[0][2]=0;
    while(t--){
        cin>>n>>q;
        tk=n;
        for(int i=1;i<=n;i++)
            bot[i]=hs[i]=tp[i]=fa[i]=0,siz[i]=1,gr[i].clear();
        for(int i=2;i<=n;i++){
            cin>>fa[i];
            gr[fa[i]].push_back(i);
        }
        for(int i=1;i<=n;i++){
            int x;
            cin>>x;
            s[i]=-x;
            g[i]=-x;
            h[i]=0;
            f[i]=-x;
        }
        for(int i=n;i>1;i--){
            siz[fa[i]]+=siz[i];
            if(siz[i]>siz[hs[fa[i]]])hs[fa[i]]=i;
        }
        // for(int i=2;i<=n;i++)
        // cout<<fa[i]<<" "<<i<<endl;
        // for(int i=1;i<=n;i++)
        // cout<<hs[i]<<" ";
        // cout<<endl;
        dfs(1,1);
        // for(int i=1;i<=n;i++)
        // cout<<i<<" "<<tp[i]<<" "<<bot[i]<<endl;
        // return 0;
        for(int i=n;i>1;i--){
            f[fa[i]]+=f[i];
            if(i!=hs[fa[i]]){
                s[fa[i]]+=f[i];
                h[fa[i]]+=f[i];
                g[fa[i]]+=f[i];
            }
        }
        for(int i=1;i<=n;i++)mf[i]=min(0ll,f[i]);   
        bd(1,1,n);
        // cout<<bot[3]<<" "<<dfn[bot[3]]<<" "<<dfn[3]<<endl;
        // cout<<s[3]<<" "<<g[3]<<" "<<h[3]<<endl;
        // cout<<F(3)<<endl;
        while(q--){
            int op,x,y;
            cin>>op>>x>>y;
            if(op==1)add(x,y,0);
            else add(x,0,y);
            // continue;
            // cout<<g[1]<<" "<<h[1]<<endl;
            cout<<F(1)<<" "<<F(3)<<" "<<s[3]<<" "<<g[3]<<" "<<h[3]<<" ";
            if(F(1)<0)cout<<"NO"<<endl;
            else cout<<"YES"<<endl;
            // exit(0);
        }
    }
    
    cout.flush();
    return 0;
}
2024/11/8 09:27
加载中...