【堆】小Z的AK计划

题目链接

大根堆维护扫过的机房中,可取的$t[i]$

每次向右扫一个单位,并将此位置的$t$压入堆中,记录总时间

while(超时) 不要堆顶的机房;

记录ans与当前cnt取max

ans即为所求

注意规避不合法情况

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;

const int MAXN=1e5+5;

int n,ans,id,cnt;
int hp[MAXN];
bool vis[MAXN];
long long m,sum;
struct rpg{
    long long x;
    int t;
}a[MAXN];

bool cmp(rpg a,rpg b){return a.x<b.x;}

void ins(int x)
{
    hp[++hp[0]]=x;
    for(int i=hp[0],j=hp[0]>>1;j;i=j,j>>=1){
        if(a[hp[i]].t>a[hp[j]].t) swap(hp[i],hp[j]);
        else break;
    }return;
}

void pop()
{
    hp[1]=hp[hp[0]--];
    for(int i=1,j=2;j<=hp[0];i=j,j<<=1){
        if(j<hp[0]&&a[hp[j]].t<a[hp[j+1]].t) ++j;
        if(a[hp[i]].t<a[hp[j]].t) swap(hp[i],hp[j]);
        else break;
    }return;
}

int main()
{
    scanf("%d%lld",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%lld%d",&a[i].x,&a[i].t);
        if(a[i].x>m||a[i].t>m) --i,--n;
    }sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;++i){
        sum+=a[i].x-a[i-1].x+a[i].t;ins(i);++cnt;
        while(sum>m){
            sum-=a[hp[1]].t;
            --cnt;
        }ans=max(ans,cnt);
    }printf("%d\n",ans);
    return 0;
}
/*
3 10
1 1
3 6
5 3
*/