CSP-S2023 T4 15分求调
查看原帖
CSP-S2023 T4 15分求调
511389
xibaohe_KarlPeter楼主2023/10/23 21:42

这个check函数指定有点问题 我知道log^2会被卡常

#include <bits/stdc++.h>

using namespace std;

const int N=1e5+10,M=2e5+10;
long long a[N],b[N],c[N],last[N],lis[N];
int head[N],vtex[M],nxt[M],fa[N];
int idex=1,n;

void addEdge(int x,int y)
{
    nxt[idex]=head[x];
    head[x]=idex;
    vtex[idex]=y;
    idex++;
}

long long cal(int x,__int128 lim)
{
    __int128 res=0,day=0;
    bool flag=false;
    if(c[x]<0){
        if(lim*c[x]+b[x]<=1){
            flag=true;
            day=(1-b[x])/c[x];
            //if((c[x]-1)*day==1-b[x]) day--;
            res=day*((day+1)*c[x]+(__int128)2*b[x])>>1;
            res+=(lim-day);
        }
        else
            res=lim*((lim+1)*c[x]+(__int128)2*b[x])>>1;
    }
    else if(c[x]==0)
        res=b[x]*lim;
    else
        res=lim*((lim+1)+c[x]+(__int128)2*b[x])>>1;
    if(res<a[x]) return -1;
    long long l=1,r=lim;
    while(l<r){
        long long mid=r+l+1>>1;
        __int128 res_2=0;
        if(flag){
            if(mid<=day) res_2=mid*((mid+1)*c[x]+(__int128)2*b[x])>>1;
            else res_2=day*(((day+1)*c[x]+(__int128)2*b[x])>>1)+(mid-day);
        }
        else res_2=mid*((mid+1)*c[x]+(__int128)2*b[x])>>1;
        //if(x==4 && lim==5) cout<<x<<" "<<(long long)day<<" "<<(long long)res<<" "<<(long long)res_2<<" "<<mid<<endl;
        //if(x==2 && lim==5) cout<<x<<" "<<(long long)day<<" "<<(long long)res<<" "<<(long long)res_2<<" "<<mid<<endl;
        if(res-res_2<a[x])
            r=mid-1;
        else l=mid;
    }
    return min(l+1,(long long)lim);
}

long long check(int x,int father)
{
    long long start=last[x];
    int tmp=head[x],tot=0;
    while(tmp){
        if(vtex[tmp]!=father){
            long long res=check(vtex[tmp],x);
            if(res<=1) return -1;
            else lis[++tot]=res; //有问题
        }
        tmp=nxt[tmp];
    }
    sort(lis+1,lis+tot+1);
    for(int i=1;i<=tot;i++){
        start=min(start,lis[i]-i);
        if(lis[i]<=i) return 0;
    }
    return start;
}

long long binarySearch_1()
{
    long long l=1,r=1e9;
    while(l<r){
        long long mid=r+l>>1;
        bool flag=false;
        for(int i=1;i<=n;i++){
            last[i]=cal(i,mid);
            if(last[i]==-1)
                flag=true;
        }
        if(flag) l=mid+1;
        else if(check(1,0)>=1)
            r=mid;
        else l=mid+1;
    }
    return l;
}

int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i]>>b[i]>>c[i];
    for(int i=1;i<=n-1;i++){
        int x,y;
        cin>>x>>y;
        addEdge(x,y),addEdge(y,x);
    }
    cout<<binarySearch_1()<<endl;
    //for(int i=1;i<=n;i++)
     //   cout<<last[i]<<" "<<lis[i]<<endl;
    return 0;
}

2023/10/23 21:42
加载中...