P3793-由乃救爷爷【分块,ST表】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P3793


1|1题目大意

给出n个数字的一个序列m次询问区间最大值

保证数据随机

1n,m2×107


1|2解题思路

使用ST表可以做到O(1)询问,但是预处理的时空复杂度都是O(nlogn),且自带大常数导致过不了。

如何加快预处理的时间,(因为是lxl的题目所以)考虑使用分块。每次询问可以分为整块的部分和不是整块的零散部分。

去掉没有跨块的情况,那么零散的部分就是块内前后缀最大值。然后整块的部分用ST表就好了。

那么没有跨块的情况是不是还需要给每个块维护一个ST表?这样空间还是过不了,其实可以考虑将没有跨块的情况按顺序每个块每个块离线处理,这样就可以过了。

但是数据保证随机,所以随机到同一个块内的概率是1T,也就是期望n次,暴力处理是O(n)的,所以直接暴力处理就可以了

时间复杂度O(nlogn+m)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=2e7+10; namespace GenHelper{ unsigned z1,z2,z3,z4,b; unsigned rand_() { b=((z1<<6)^z1)>>13; z1=((z1&4294967294U)<<18)^b; b=((z2<<2)^z2)>>27; z2=((z2&4294967288U)<<2)^b; b=((z3<<13)^z3)>>21; z3=((z3&4294967280U)<<7)^b; b=((z4<<3)^z4)>>12; z4=((z4&4294967168U)<<13)^b; return (z1^z2^z3^z4); } } void srand(unsigned x) {using namespace GenHelper; z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;} int read() { using namespace GenHelper; int a=rand_()&32767; int b=rand_()&32767; return a*32768+b; } int n,m,a[N],lg[N],p[N],q[N],g[5000][13]; int L[5000],R[5000],pos[N]; unsigned s; unsigned long long ans; int AskT(int l,int r){ if(l>r)return 0;int z=lg[r-l+1]; return max(g[l][z],g[r-(1<<z)+1][z]); } int main() { scanf("%d%d%u",&n,&m,&s); srand(s); for(int i=1;i<=n;i++)a[i]=read(); int T=sqrt(n); for(int i=1;i<=T;i++) L[i]=R[i-1]+1,R[i]=i*T; if(R[T]!=n)++T,L[T]=R[T-1]+1,R[T]=n; for(int i=1;i<=T;i++){ for(int j=L[i];j<=R[i];j++)pos[j]=i,g[i][0]=max(g[i][0],a[j]); p[L[i]]=a[L[i]];q[R[i]]=a[R[i]]; for(int j=L[i]+1;j<=R[i];j++)p[j]=max(p[j-1],a[j]); for(int j=R[i]-1;j>=L[i];j--)q[j]=max(q[j+1],a[j]); } for(int j=1;(1<<j)<=T;j++) for(int i=1;i+(1<<j)-1<=T;i++) g[i][j]=max(g[i][j-1],g[i+(1<<j-1)][j-1]); for(int i=2;i<=T;i++)lg[i]=lg[i>>1]+1; for(int i=1;i<=m;i++){ int l=read(),r=read(); l=l%n+1;r=r%n+1; if(l>r)swap(l,r); int x=pos[l],y=pos[r]; int tmp=0; if(x==y){ for(int i=l;i<=r;i++) tmp=max(tmp,a[i]); } else{ tmp=AskT(x+1,y-1); tmp=max(tmp,max(q[l],p[r])); } ans+=tmp; } printf("%llu\n",ans); }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14526308.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(99)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示