CF1662I Ice Cream Shop 题解
题目大意
在沙滩上有 个小屋,可以看做小屋在一条数轴上,第 个小屋的位置为 ,里面有 个人。这条数轴上还有 个小屋,每个买冰淇淋的商店,第 个商店的位置为 。
现在你可以再数轴上任意一个位置(不需要为整数!)开一个冰淇淋商店,如果一个小屋到你开的冰淇淋店的距离比原有所以的冰淇淋点更加近,那么这个小屋里面所有的人都会到你开的冰淇淋店买冰淇淋。
注意可能存在冰淇淋店和小屋在同一位置,你开的冰淇淋店也可以和小屋在同一位置。
现在求到你开的冰淇淋店买冰淇淋的人的最大人数。
,保证 互不相等。
题目解析
我们可以先求出第 个小屋的人到你开的冰淇淋店来买冰淇淋,需要满足冰淇淋店的位置(一个开区间 ),不难发现,如果设 为距离第 个小屋最近的冰淇淋店的位置,那么这个序列不降,所以只需要将冰淇淋店的坐标从小到大排序然后扫一次就好了。
这样就相当于每个区间存在一个价值,然后选择若干区间使得这些区间的交集不为空,然后求最大的价值。
然后只需要按照左端点排序,开一个 set
维护包含第 个区间,并且和这个区间交集不为空的区间即可。
复杂度
核心代码:
int n,m,dis[maxn],tmp; ll sum,ans; struct JTZ{ int l,r,p; bool operator < (const JTZ x) const { return this->r<x.r; } }a[maxn]; int cmp(JTZ x,JTZ y){ return x.l<y.l; } multiset<JTZ> s; #define dis(i) (((i)-1)*100) int main(){ //freopen(".in","r",stdin); //freopen(".out","w",stdout); n=read(); m=read(); int i,j; for(i=1;i<=n;i++) a[i].p=read(); for(i=1;i<=m;i++) dis[i]=read(); sort(dis+1,dis+m+1); j=1; for(i=1;i<=n;i++){ while(j<m&&mabs(dis[j]-dis(i))>mabs(dis[j+1]-dis(i))) j++; tmp=mabs(dis[j]-dis(i)); a[i].l=dis(i)-tmp,a[i].r=dis(i)+tmp; } sort(a+1,a+n+1,cmp); s.clear(); set<JTZ>::iterator it; for(i=1;i<=n;i++) if(a[i].l<a[i].r){ if(!s.empty()){ it=s.begin(); while((*it).r<=a[i].l){ sum-=(*it).p; s.erase(it); if(!s.empty()) it=s.cbegin(); else break; } } sum+=a[i].p; s.insert(a[i]); ans=mmax(ans,sum); } print(ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具