题解 P3865 【模板】ST表(回滚莫队版)

莫队日报


题目link


打广告


虽然是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);
    }
}
posted @ 2019-03-01 20:40  G_A_TS  阅读(507)  评论(0编辑  收藏  举报