一种 O(n)-O(1) 的 RMQ 算法
https://www.luogu.com/article/ey6cxlv5
考虑将原序列分块,块长为
而对于散块,预处理一下块内的前缀后缀最大值即可。
但是这个算法会在
考虑单调栈,若要查询 单调栈本身的意义这个东西啊)。正常情况下需要二分,但由于我们的序列长只有 __builtin_ctz
干的事情,然后就可以
code(P3793):
点击查看代码
const int maxn=2e7+5,maxm=8e5+5,inf=0x3f3f3f3f,B=25;
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()
{
// return rd<int>();
using namespace GenHelper;
int a=rand_()&32767;
int b=rand_()&32767;
return a*32768+b;
}
int n,Q,a[maxn],num;
inline int bel(int x){
return (x-1)/B+1;
}
inline int getl(int x){
return (x-1)*B+1;
}
inline int getr(int x){
return min(x*B,n);
}
int f[maxm][25],lg[maxm];
int sta[maxn],tp;
int st[maxn];
void init(){
rep(i,2,num)lg[i]=lg[i>>1]+1;
const int M=lg[num];
rep(j,1,M)rep(i,1,num-(1<<j)+1)f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
int qry_1(int l,int r){
const int L=getl(bel(l));
return a[l+__builtin_ctz(st[r]>>(l-L))];
}
int qry_2(int l,int r){
if(l>r)return ~0x7fffffff;
int p=lg[r-l+1];
return max(f[l][p],f[r-(1<<p)+1][p]);
}
int sec[maxn],pre[maxn];
inline void solve_the_problem(){
unsigned s;
n=rd<int>(),Q=rd<int>(),s=rd<unsigned>();
srand(s);
rep(i,1,n)a[i]=read();
num=(n+B-1)/B;
rep(k,1,num){
const int L=getl(k),R=getr(k);
int mx=0;
rep(i,L,R)mx=max(mx,a[i]);
f[k][0]=mx;
pre[L]=a[L];
rep(i,L+1,R)pre[i]=max(pre[i-1],a[i]);
sec[R]=a[R];
per(i,R-1,L)sec[i]=max(sec[i+1],a[i]);
tp=0;
int lst=0;
rep(i,L,R){
while(tp&&a[i]>a[sta[tp]])lst^=(1<<(sta[tp]-L)),--tp;
lst|=(1<<(i-L)),sta[++tp]=i,st[i]=lst;
}
}
init();
u64 ans=0;
while(Q--){
int l=read()%n+1,r=read()%n+1;
if(l>r)swap(l,r);
if(bel(l)==bel(r))ans+=qry_1(l,r);
else ans+=max({sec[l],pre[r],qry_2(bel(l)+1,bel(r)-1)});
}
write(ans);
}
当数据随机的时候(就是 P3793),考虑这样一种做法:
整块处理部分和上面一样,当
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2024-01-28 一个题
2024-01-28 CF337E Divisor Tree
2024-01-28 Gym104270E Kawa Exam
2024-01-28 CF1924D Balanced Subsequences