假设初始人数为0,
将每个时刻在等待的人数写下来,就是求个和。
如果纵坐标看成人数,横坐标看成时间,就是求个面积。
因为初始人数不一定为零,所以离线后扫描线即可回答所有询问。
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int n,m,e; struct LINE{ int y,l,id; }ls[200010]; bool cmp(const LINE &a,const LINE &b){ return a.y!=b.y ? a.y>b.y : a.l<b.l; } ll anss[100010]; int main(){ freopen("expect.in","r",stdin); freopen("expect.out","w",stdout); int x,y; char op[4]; scanf("%d%d",&n,&m); int now=0,last=1; for(int i=1;i<=n;++i){ scanf("%s%d%d",op,&x,&y); if(now>0 && i>1){ ls[++e]=(LINE){now,x-last}; } if(op[0]==‘+‘){ now-=y; } else{ now+=y; } last=x; } if(now>0){ ls[++e]=(LINE){now,1000000001}; } for(int i=1;i<=m;++i){ ++e; scanf("%d",&ls[e].y); ls[e].id=i; ls[e].l=0; } sort(ls+1,ls+e+1,cmp); ll nowans=0; int nowl=0; int i=1; for(;i<=e;++i){ if(ls[i].l==0){ anss[ls[i].id]=nowans; } if(ls[i].y>0 && ls[i].l==1000000001){ break; } nowl+=(ll)ls[i].l; if(ls[i].y!=ls[i+1].y){ nowans+=(ll)(ls[i].y-ls[i+1].y)*(ll)nowl; } } for(;i<=e;++i)if(ls[i].l==0){ anss[ls[i].id]=-1; } for(i=1;i<=m;++i){ if(anss[i]==-1){ puts("INFINITY"); } else{ printf("%I64d\n",anss[i]); } } return 0; }
时间: 2024-10-06 22:35:48