• [NOIP模拟赛] seq


    seq

    试题分析

    介绍一种方法叫做回滚莫队。

    • 回滚莫队是一种只加不删的莫队。
      首先处理(l,r)都在同一个块内的询问,暴力即可。
      然后对于(l,r)不同在一个块,我们将左端点挂在其所在的块。
      将挂在每个块上的右端点排序,这样对于左边我们每次暴力滚回当前块的右端点,这里可以用主席树之类的数据结构维护。
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<algorithm>
     
    using namespace std;
    #define LL long long
     
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int INF = 2147483600;
    const int MAXN = 100000;
     
    int N,M; int a[MAXN+1];
    int bel[MAXN+1];
    struct data{int l,r,id;}q[MAXN+1];
     
    bool cmp(data a,data b){
        if(bel[a.l]!=bel[b.l]) return bel[a.l]<bel[b.l];
        return a.r<b.r;
    }
    int L[MAXN+1],R[MAXN+1]; int res;
    inline void init_over(){
        res=0; memset(L,0,sizeof(L));
        memset(R,0,sizeof(R)); return ;
    }
    struct stak{int pos,x;}staR[MAXN+1],staL[MAXN+1];
    int ans[MAXN+1];
     
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        N=read(),M=read(); int sqr=(int)sqrt(N)+100,top;
        for(int i=1;i<=N;i++) a[i]=read();
        for(int i=1;i<=M;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
        for(int i=1;i<=N;i++) bel[i]=(i-1)/sqr+1;
        sort(q+1,q+M+1,cmp); int l=bel[q[1].l]*sqr,r=bel[q[1].l]*sqr;
        for(int i=1;i<=M;i++){
            //cout<<q[i].l<<" "<<q[i].r<<":"<<bel[q[i].l]<<" "<<bel[q[i].r]<<endl;
            l=bel[q[i].l]*sqr; //l=min(l,N);
            if(bel[q[i].l]!=bel[q[i-1].l]) r=bel[q[i].l]*sqr,init_over();
            /*if(bel[q[i].l]==bel[q[i].r]){
                res=0;
                for(int j=q[i].l;j<=q[i].r;j++){
                    res=max(res,L[a[j]-1]+R[a[j]+1]+1);
                    R[a[j]-L[a[j]-1]]=L[a[j]+R[a[j]+1]]=L[a[j]-1]+R[a[j]+1]+1;
                }
                ans[q[i].id]=res;
                for(int j=q[i].l;j<=q[i].r;j++) L[a[j]]=R[a[j]]=0;
                continue;
            }*/
            while(r<q[i].r){
                ++r; res=max(res,L[a[r]-1]+R[a[r]+1]+1);
                R[a[r]-L[a[r]-1]]=L[a[r]+R[a[r]+1]]=L[a[r]-1]+R[a[r]+1]+1;
            } top=0;
            int res2=res;
            for(l=min(l,q[i].r);l>=q[i].l;--l){
                res2=max(res2,L[a[l]-1]+R[a[l]+1]+1); 
                int ll=a[l]-L[a[l]-1],rr=a[l]+R[a[l]+1];
                staR[++top].pos=ll; staR[top].x=R[ll];
                staL[top].pos=rr; staL[top].x=L[rr];
                R[ll]=L[rr]=L[a[l]-1]+R[a[l]+1]+1;
            } ans[q[i].id]=res2;
            for(;top;--top){
                R[staR[top].pos]=staR[top].x;
                L[staL[top].pos]=staL[top].x;
            }
        }
        for(int i=1;i<=M;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    [MFC] MFC 用mciSendString加载WAV资源文件
    [JS] HTML QQ分享界面js代码
    [MFC] MFC 打开HTML资源(用ID版,也可加载到自己的web控件上)
    [ACM_暴力][ACM_几何] ZOJ 1426 Counting Rectangles (水平竖直线段组成的矩形个数,暴力)
    [ACM_动态规划] ZOJ 1425 Crossed Matchings(交叉最大匹配 动态规划)
    easyui combobox可编辑的情况下,只能首字母开始过滤的问题选项
    easyui-combobox绑定回车事件注意事项
    easyui-combobox绑定回车事件相关
    jquery-qrcode 生成和读取二维码
    zxing生成二维码和读取二维码
  • 原文地址:https://www.cnblogs.com/wxjor/p/9527818.html
Copyright © 2020-2023  润新知