S-T2 求调
查看原帖
S-T2 求调
590600
Kreado楼主2024/10/13 19:00

个人感觉思路挺对的,大样例也过完了、

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

const int Maxn=2e5+4;
const ll inf=1e12;
int type;
int T;
int n;
int f[Maxn];
ll a[Maxn];
vector<int>e[Maxn];
ll dp[Maxn],ddp[Maxn];
bool tag;

inline ll qread(){
    ll x=0;bool f=0;char ch;
    while((ch=getchar())&&(ch>'9'||ch<'0')) if(ch=='-') f=1;
    x=(ch^48);
    while((ch=getchar())&&(ch<='9'&&ch>='0')) x=x*10+(ch^48);
    return f?-x:x;
}

void dfs(int u){

    if(a[u]<0) {
        ddp[u]=inf;
        return ;
    }
    if(e[u].empty()){
        dp[u]=a[u];
        ddp[u]=inf;
        return ;
    }

    int son=0;ll sm=0;
    for(auto v:e[u]){
        dfs(v);
        dp[u]+=dp[v];
        ddp[u]+=ddp[v];
        sm+=a[v];
        son++;
    }
    if(sm>a[u]) tag=0;

    if(dp[u]>a[u]) tag=0;
    if(dp[u]<a[u]) dp[u]=a[u];

    if(son==1) ;
    else{
        ll l=0,r=2e18,k=0;
        while(l<=r){
            ll mid=l+r>>1;

            ll nsm=0;
            for(auto v:e[u]){
                ll p=a[v]+mid;
                if(p>0) nsm+=p;
                if(nsm>a[u]+mid) break;
            }
            if(a[u]+mid>=nsm) l=mid+1,k=mid;
            else r=mid-1;
        }

        for(auto v:e[u]) k=min(k,ddp[v]-a[v]);

        ddp[u]=min(ddp[u],a[u]+k);
    }

    if(ddp[u]<a[u]) tag=0;
}

int main(){
    scanf("%d",&type);
    scanf("%d",&T);

    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) e[i].resize(0),dp[i]=0,ddp[i]=0;

        for(int i=2;i<=n;i++) f[i]=qread(),e[f[i]].emplace_back(i);
        for(int i=1;i<=n;i++) a[i]=qread();

        tag=1;
        for(int i=2;i<=n;i++) if(a[f[i]]<a[i]) tag=0;
        if(!tag){
            puts("Shuiniao");
            continue;
        }
        dfs(1);
        if(tag) puts("Huoyu");
        else puts("Shuiniao");
    }	

    system("pause");
        
	return 0;
}


2024/10/13 19:00
加载中...