MnZn求助 玄关
查看原帖
MnZn求助 玄关
311306
dk_qwq楼主2024/9/28 23:46

秋秋了,调了一年了(雾

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<algorithm>
#define pb push_back
using namespace std;
namespace INPUT{
    char buf[1<<20],*p1,*p2;
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
T read(){
    char ch=gc();
    T x=0,p=1;
    while(ch<'0'||ch>'9'){
        if(ch=='-') p=-1;
        ch=gc();
    }
    while(ch<='9'&&ch>='0'){
        x=(x<<3)+(x<<1)+(ch^48);
        ch=gc();
    }
    return x*p;
}
const int N=1e5+5;
vector<int>G[N];
void add(int u,int v){G[u].pb(v),G[v].pb(u);}
int fa[N];
void dfs(int u,int f){
    fa[u]=f;
    for(auto v:G[u])
        if(v!=f) dfs(v,u);
}
int n;
#define ll long long
ll a[N],b[N],c[N];
ll calc(int i,ll l,ll r){
    if(c[i]>=0) return b[i]*(r-l+1)+(r-l+1)*(l+r)/2*c[i];
    ll T=(1-b[i])/c[i];
    if(T<l) return r-l+1;
    if(T>r) return b[i]*(r-l+1)+(r-l+1)*(l+r)/2*c[i];
    return b[i]*(T-l+1)+(T-l+1)*(l+T)/2*c[i]+r-T;
}
int id[N],t[N];
bool vis[N];
bool check(int r){
    memset(vis,0,sizeof(vis)),vis[0]=true;
    for(int i=1;i<=n;i++){
        if(calc(i,1,r)<a[i]) return false;
        int dl=1,dr=n,dm;
        while(dl<dr){
            dm=(dl+dr+1)>>1;
            if(calc(i,dm,r)>=a[i]) dl=dm;
            else dr=dm-1;
        }
        id[i]=i,t[i]=dl;
    }
    sort(id+1,id+1+n,[](int A,int B){return t[A]<t[B];});
    int nowt=0;
    stack<int>s;
    for(int i=1;i<=n;i++){
        int u=id[i];
        while(!vis[u]) s.push(u),u=fa[u];
        while(!s.empty()) {
            vis[s.top()]=true,nowt++;
            if(nowt>t[s.top()]) return false;
            s.pop();
        }
    }
    return true;
}
int main(){
    // freopen("P9755_2.in","r",stdin);
    // freopen("P9755_2.out","w",stdout);
    n=read<int>();
    for(int i=1;i<=n;i++) a[i]=read<ll>(),b[i]=read<int>(),c[i]=read<int>();
    for(int i=1;i<n;i++) add(read<int>(),read<int>());
    dfs(1,0);
    // cout<<check(25526156)<<endl;
    int l=n,r=1e9,mid;
    while(l<r){
        mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    cout<<l<<endl;
}
2024/9/28 23:46
加载中...