多校day1-3 训练

来源:互联网 发布:中国去穆斯林化 知乎 编辑:程序博客网 时间:2024/05/02 18:32

钓鱼式的贪心(张老师的钓鱼真是万金油)
用堆维护还没走完的楼层

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#define ll long long using namespace std;int n,tot;ll Time,m,ans,s; int h[1000005],v[1000005],w[1000005];struct ty{    int v,h,id;}heap[1000005];void down(int id){    while(id*2<=tot)     {        int j;        if(id*2+1>tot||heap[id*2+1].v<heap[id*2].v) j=id*2; else j=id*2+1;        if(heap[id].v<heap[j].v)         {            swap(heap[id],heap[j]);            id=j;        }        else break;    }}void up(int id){    while(id/2>=1)     {        if(heap[id].v>heap[id/2].v)         {            swap(heap[id],heap[id/2]);            id=id/2;        }        else break;    }}int main(){    cin>>n>>m;    for(int i=1;i<=n;i++)    {        scanf("%d%d",&h[i],&v[i]);        s=s+v[i];        w[i]=1;        if(h[i]>1)         {            tot++;            heap[tot].v=v[i];            heap[tot].h=h[i]-1;            heap[tot].id=i;             up(tot);        }    }    Time=m-(n-1);    for(int i=n;i>=1;i--)     {        if(i+1<=n)         {            Time=Time+w[i+1]; //后面那幢楼已经去不了了,把花在那幢楼的时间加上             s=s-(ll)(w[i+1])*v[i+1]; //收益减去         }        while(Time>0&&tot>0)         {            while(tot>0&&heap[1].id>i)             {                swap(heap[1],heap[tot]);                tot--;                down(1);            }            if(tot==0) break;             if(Time>=heap[1].h)             {                Time-=heap[1].h;                 w[heap[1].id]+=heap[1].h;                s=s+(ll)(heap[1].v)*heap[1].h;                swap(heap[1],heap[tot]);                tot--;                down(1);             }            else            {                w[heap[1].id]+=Time;                s=s+(ll)(heap[1].v)*(Time);                heap[1].h-=Time;                 Time=0;             }        }         if(Time==0) ans=max(ans,s);        if(Time>0&&tot==0) ans=max(ans,s);       }    cout<<ans;     return 0;}
0 0