洛谷P3434 [POI2006]KRA-The Disks(线段树)
洛谷题目传送门
的正解算法对我这个小蒟蒻真的还有点思维难度。洛谷题解里都讲得很好。
考试的时候一看到300000就直接去想各种带log的做法了,反正不怕T。。。。。。
我永远只会有最直观的思路(最差的程序效率)
题目相当于每次让我们找区间中上数第一个比当前盘子半径小的位置(las为上一次盘子掉到的位置)于是用线段树无脑搞一下,维护区间最小值,每次找这个位置,能往左跳就往左,不能的话再往右,当然如果超过了las-1就不用找了,直接放在las上面(相当于las--)直到全部放完或las=0为止。
#include<cstdio>
#define R register int
#define lc u<<1
#define rc u<<1|1
#define G c=getchar()
#define min2(x,y) x<y?x:y
#define in(z) G;\
while(c<'-')G;\
z=c&15;G;\
while(c>'-')z*=10,z+=c&15,G
const int N=300009,M=10000009;
int las,k,a[N],mina[M];//mina记录最小值
void build(R u,R l,R r){
if(l==r){
mina[u]=a[l];
return;
}
R m=(l+r)>>1;
build(lc,l,m);build(rc,m+1,r);
mina[u]=min2(mina[lc],mina[rc]);
}
int ask(R u,R l,R r){
if(l==r)return l-1;
R m=(l+r)>>1;
//因为要找位置最靠前的,所以优先往左
if(mina[lc]<k)return ask(lc,l,m);
if(m<las-1&&mina[rc]<k)return ask(rc,m+1,r);//m要小于las-1
return las-1;
}
int main(){
R n,m;
register char c;
in(n);in(m);las=n+1;
for(R i=1;i<=n;++i){in(a[i]);}
build(1,1,n);
while(m--&&las){//las=0直接就不放了
in(k);
las=ask(1,1,n);
}
printf("%d\n",las);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具