zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    「UVA12293」 Box Game
    「CF803C」 Maximal GCD
    「CF525D」Arthur and Walls
    「CF442C」 Artem and Array
    LeetCode lcci 16.03 交点
    LeetCode 1305 两棵二叉搜索树中的所有元素
    LeetCode 1040 移动石子直到连续 II
    LeetCode 664 奇怪的打印机
    iOS UIPageViewController系统方法崩溃修复
    LeetCode 334 递增的三元子序列
  • 原文地址:https://www.cnblogs.com/wxjor/p/9527818.html
Copyright © 2011-2022 走看看