MnZn 求助 大佬
查看原帖
MnZn 求助 大佬
414386
Isshiki·Iroha楼主2023/11/14 22:10

我的思路和题解差不多,就是判断可行性那里我先算出对于每一个 ii 能长到 ii 的最晚天数,然后 dfs 处理要满足 ii 的子树时的最晚天数,对于然后记 sumisum_i 表示最晚天数小于 ii 天的点的个数,那么可行性就是对于所有的 ii sumi≤isum_i \le i,等价于差分数组都为非负数,但是只有 1~8 的40 pts,思路有什么问题吗?

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lll __int128
#define ull unsigned ll
#define ld long double 
#define db double
template<typename T>inline void read(T& x) {
    x=0;int f=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=~f+1;ch=getchar();}
    while (isdigit (ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    x*=f;
}
template <typename T,typename... Args> inline void read(T& x, Args&... args) {
    read(x);
    read(args...);
}
template<typename T>inline void write(T x) {
    static int buf[40],top=0;
    if(x<0)putchar('-'),x=~x+1;
    while(x)buf[++top]=x%10,x/=10;
    if(top==0)buf[++top]=0;
    while (top) putchar(buf[top--]^48);
    putchar(' ');
}
template <typename T,typename... Args> inline void write(T x, Args... args) {
    write(x);
    write(args...);
}
template<typename T>inline T Max(T a,T b){
    return a>b?a:b;
}
template<typename T,typename ...Args>inline T Max(T a,T b,Args... args){
    return Max(a,Max(b,args...));
}
template<typename T>inline T Min(T a,T b){
    return a<b?a:b;
}
template<typename T,typename ...Args>inline T Min(T a,T b,Args... args){
    return Min(a,Min(b,args...));
}
const int maxn=1e5+10;
int n,T;
vector<int>son[maxn];
ll a[maxn],b[maxn],c[maxn],ropz[maxn];
// -1 Impossible to > 1 ;-2 >1 permanently
ll calc(int i,int s,int t){
    if(c[i]==0){
        return (t-s+1)*1ll*(b[i]>=1?b[i]:1);
    }
    else if(c[i]>0){
        if(ropz[i]<s){
            return (t-s+1)*1ll*b[i]+(t+s)*1ll*(t-s+1)/2*c[i]*1ll;
        }
        else if(ropz[i]>t){
            return t-s+1;
        }
        else {
            return ropz[i]-s+(t-ropz[i]+1)*1ll*b[i]+(ropz[i]+t)*1ll*(t-ropz[i]+1)/2*c[i]*1ll;
        }
    }
    else{
        if(ropz[i]>t){
            return (t-s+1)*1ll*b[i]+(t+s)*1ll*(t-s+1)/2*c[i]*1ll;
        }
        else if(ropz[i]<s){
            return t-s+1;
        }
        else {
            return t-ropz[i]+(ropz[i]-s+1)*1ll*b[i]+(ropz[i]+s)*1ll*(ropz[i]-s+1)/2*c[i]*1ll;;
        }
    }
}
int Find(int i,int E){
    int l=1,r=E-1,ans=1;
    while(l<=r){
        int mid=l+r>>1;
        if(calc(i,mid,E)>=a[i]){
            ans=mid;
            l=mid+1;
        }
        else {
            r=mid-1;
        }
    }
    return ans;
}
int st[maxn];
void dfs(int u,int fa){
    sort(son[u].begin(),son[u].end(),[](int A,int B){
        return st[A]>st[B];
    });
    for(int v:son[u]){
        if(v==fa)continue;
        dfs(v,u);
    }
    for(int i(1);i<(int)son[u].size();++i){
        if(son[u][i]==fa)continue;
        else if(son[u][i-1]==fa){
            if(i>1){
                if(st[son[u][i]]==st[son[u][i-2]]){
                    st[son[u][i]]--;
                }
            }
        }
        else if(st[son[u][i]]==st[son[u][i-1]]){
            st[son[u][i]]--;
        }
        st[u]=min(st[u],st[son[u][i]]-1);
    }
    // write(u,st[u]);
    // puts("::");
    // for(int v:son[u]){
    //     if(v==fa)continue;
    //     write(v,st[v]);
    //     puts("");
    // }
    // puts("SS");
}
int C[maxn];
inline int lowbit(int x){
    return x&(-x);
}
inline void change(int x,int k){
    while(x<=n){
        C[x]+=k;
        x+=lowbit(x);
    }
}
inline int query(int x){
    int res=0;
    while(x>0){
        res+=C[x];
        x-=lowbit(x);
    }
    return res;
}
bool check(int x){
    for(int i(1);i<=n;++i){
        st[i]=Find(i,x);
        // write(st[i]);
        C[i]=0;
    }
    for(int i(1);i<=n;++i){
        change(i,1);
    }
    dfs(1,0);
    for(int i(1);i<=n;++i){
        // write(st[i]);
        if(st[i]<=0)return 0;
        if(st[i]>n)continue;
        change(st[i],-1);
    }
    for(int i(1);i<=n;++i){
        // write(query(i));
        if(query(i)<0)return 0;
    }
    return 1;
}
int main(){
    read(n);
    for(int i(1);i<=n;++i){
        read(a[i],b[i],c[i]);
        if(c[i]==0)ropz[i]=b[i]>=1?-1:-2;
        else if(c[i]>0){
            ropz[i]=(ll)ceil((ld)(1-b[i]+0.0)/(ld)(c[i]+0.0));
        }
        else {
            ropz[i]=(ll)floor((ld)(1-b[i]+0.0)/(ld)(c[i]+0.0));
        }
    }
    for(int i(1),u,v;i<n;++i){
        read(u,v);
        son[u].emplace_back(v);
        son[v].emplace_back(u);
    }
    // int w=check(5);
    // write(w);
    int l=1,r=1e9,ans=1e9;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)){
            r=mid-1;
            ans=mid;
        }
        else l=mid+1;
    }
    write(ans);
    return 0;
}
2023/11/14 22:10
加载中...