NOI online 2022丹钓战
看到这么个东西赛时想用莫队,但是打假了,所以就有了下面这个不三不四的代码
也就是很裸的暴力
void Push(int st,int ed){
for(int i=st;i<=ed;++i){
while(!q.empty()){
Pair tmp=q.back();
if(tmp.a == data[i].a || tmp.b<=data[i].b){
q.pop_back();
}
else break;
}
q.push_back(data[i]);
if(q.size()==1)ans++;
}
}
for(int i=1;i<=Q;++i){
que[i].l=read(),que[i].r=read(),que[i].id=i;
}
sort(que+1,que+Q+1,cmp);
int l=0,r=0;
for(int i=1;i<=Q;++i){
if(l<que[i].l){
q=deque<Pair>(),ans=0,l=que[i].l,r=que[i].r;
Push(que[i].l,que[i].r);
que[i].ans=ans;
continue;
}
if(l==que[i].l){
if(r<que[i].r){
Push(r+1,que[i].r);
r=que[i].r;
que[i].ans=ans;
continue;
}
if(r==que[i].r){
que[i].ans=ans;
continue;
}
if(r>que[i].r){
q=deque<Pair>(),ans=0,r=que[i].r;
Push(que[i].l,que[i].r);
que[i].ans=ans;
}
}
}
sort(que+1,que+Q+1,cmp1);
for(int i=1;i<=Q;++i){
printf("%d\n",que[i].ans);
}
对于每一个询问,肯定可以“成功”毋庸置疑。对于,如果满足题目中的条件就入栈,否则就是成功的。那些可以放进去的点对于答案没有贡献,暴力解法的瓶颈就在于遍历了这些没有用的点。
我们预处理出每一个点到的下一个"成功"点(初值为),查询时从到一直跳就可以了。
for(int i=1;i<=n;++i){
while(!s.empty() && !(a[i]!=a[s.top()] && b[i]<b[s.top()])){
to[s.top()]=i;s.pop();
}
s.push(i);
}
for(int i=1;i<=q;++i){
int ans=0;
int l=read(),r=read();
while(l<=r){
ans++;l=to[l];
}
printf("%d\n",ans);
}
但是如果所有的点都是成功点,这种算法会被卡到。由于是不断地往后跳可以用倍增优化
for(int i=1;i<=n;++i){
while(!s.empty() && !(a[i]!=a[s.top()] && b[i]<b[s.top()])){
to[s.top()][0]=i;s.pop();
}
s.push(i);
}
for(int i=1;i<=20;++i){
for(int j=1;j<=n;++j){
to[j][i]=to[to[j][i-1]][i-1];
}
}
for(int i=1;i<=q;++i){
int l=read(),r=read();
for(int j=20;j>=0;--j){
if(to[l][j] && to[l][j]<=r){
l=to[l][j];ans+=(1<<j);
}
}
printf("%d\n",ans);
}
民间数据倍增比不加倍增慢了将近一倍...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了