题解 P3865 【模板】ST表(回滚莫队版)
虽然是ST表模板,但我选择号称能解决一切区间查询问题的莫队
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,col[5000010],ans,L=1,R,s[5000010],FK[5000010],GG;
int fk;
struct node
{
ll l;//左
ll r;//右
ll place;//原位置
ll ANS;
}Q[5000010];//question
int cmp(node a,node b)
{
if(FK[a.l]!=FK[b.l])
return a.l<b.l;
return a.r<b.r;
}
int Cmp(node a,node b)
{
return a.place<b.place;
}
int BaoLi(int x,int y)
{
int res=-1;
for(int i=x;i<=y;i++)
{
if(col[i]>res)
{
res=col[i];
}
}
return res;
}
int md(int x,int y)
{
L=min(x*fk,n)+1;
R=L-1;
ans=0;
int RET=y;
for(int i=y;FK[Q[i].l]==x;i++)
{
if(FK[Q[i].l]==FK[Q[i].r])
{
Q[i].ANS=BaoLi(Q[i].l,Q[i].r);
}
for(;R<=Q[i].r;)
{
ans=max(ans,col[R]);
R++;
}
int fy=ans;
for(;L>=Q[i].l;)
{
ans=max(ans,col[L]);
L--;
}
Q[i].ANS=ans;
L=min(x*fk,n)+1;
ans=fy;
RET++;
}
return RET;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&col[i]);
}
fk=sqrt(n);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].place=i;
}
for(int i=1;i<=n;i++)
{
FK[i]=(i-1)/fk+1;
}
sort(Q+1,Q+m+1,cmp);
int now=1;
for(int i=1;i<=FK[n];i++)
{
now=md(i,now);
}
sort(Q+1,Q+m+1,Cmp);
for(int i=1;i<=m;i++)
{
printf("%d\n",Q[i].ANS);
}
}