代码求调(玄关)
查看原帖
代码求调(玄关)
927798
ryt47479楼主2024/8/14 17:51

不知道为什么,有两个测试点会比答案大1

// LUOGU_RID: 172619703
#include<bits/stdc++.h>
#define max(a,b) a<b?b:a
using namespace std;
#define int __int128
const int N=3e5+10;
int n,h;
__int128 read(){
    __int128 x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)&&ch!='-')ch=getchar();
    if(ch=='-')f=-1,ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
void print(__int128 x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)print(x/10);
    putchar(x%10+'0');
}

struct node{
    int d,t;
}a[N];
int sum[N],suf[N];
bool cmp(node a,node b){
    if(a.t!=b.t)return a.t>b.t;
    return a.d>b.d;
}
int cal(int l,int r){
    if(r%2==l%2)return (l+r)/2*(r-l+1);
    return (r-l+1)/2*(l+r);
}
bool check(int x){
    int top=1;
    int ss=0;
    int hp=h;
    while(top<=n&&a[top].t>x)++top;
    while(top<=n){
        int ret=0;
        ret=max(ret,sum[top]*(__int128)(x-a[top].t+1));
        ret=max(ret,suf[top-1]*cal(a[top].t,x));
        //if(hp<=ret)return true;
        x=a[top].t-1;
        ss+=ret;
        while(top<=n&&a[top].t>x)++top;
        
    }
    if(x>0){
        int ret=suf[top-1]*cal((__int128)1,x);
        ret=max(ret,sum[top]*(x-a[top].t+1));
        ss+=ret;
        x=0;
    }
    //print(ss);
    //cout<<endl;
    return hp<=ss;
        
}
map<int,int>f;
signed main(){
    //freopen("hack.in","r",stdin);
    //freopen("m2.out","w",stdout);
    n=read();
    h=read();
    for(int i=1;i<=n;i++){
        a[i].t=read();
        a[i].d=read();
        f[a[i].t]=max(f[a[i].t],a[i].d);
    }
    for(int i=1;i<=n;i++)
        a[i].d=f[a[i].t];
    sort(a+1,a+n+1,cmp);
    for(int i=n;i>=1;i--)
        sum[i]=max(sum[i+1],a[i].d*a[i].t);
    for(int i=1;i<=n;i++)
        suf[i]=max(suf[i-1],a[i].d);
    int ans=0;
    for(int i=1ll<<62;i;i>>=1)
           if(ans+i<=h&&check(ans+i)==false)ans+=i;
     ++ans;
     print(ans);
    return 0;
}
2024/8/14 17:51
加载中...