操作:

D:单点修改;
Q:查询该点所在的最大连续区间长度;
R:把最近一次删除的点还原;
  我一开始的思路是:对于最长连续区间长度的查询,用的是set来存储之前被删除的点(目的是让点排好序),用数组模拟一下栈按删除顺序存点,对于当前要查找的点,利用二分查找找到set中第一个大于等于该位置的点,和前一个点作差,直接求出。

#include <bits/stdc++.h>
using namespace std;
const int N=5e4+5;
int a[N];
set<int>st;
int n,m,cnt;
int main()
{
    int p;
    set<int>::iterator it;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(a,0,sizeof(a));
        st.clear();
        cnt=0;
        char ss[10];
        for(int i=1;i<=m;i++)
        {
            scanf("%s",ss);
            if(ss[0]=='D')
            {
                scanf("%d",&p);
                st.insert(p);
                a[++cnt]=p;
            }
            else if(ss[0]=='Q')
            {
                scanf("%d",&p);
                if(st.empty())
                    printf("%d\n",n);
                else
                {
                    int ans=0;
                    it=st.lower_bound(p);//cout<<"it="<<*it<<endl;
                    if(it==st.end())
                        ans=n-*st.rbegin();
                    if(*it!=p&&it!=st.end())
                    {
                        int t=*it;
                        if(it!=st.begin())
                        {
                            it--;
                            ans=t-*it-1;
                        }
                        else
                            ans=*it-1;
                    }
                    printf("%d\n",ans);
                }
            }
            else if(ss[0]=='R')
            {
                if(cnt>0)
                {
                    p=a[cnt--];//cout<<"p="<<p<<endl;
                    st.erase(p);
                }
            }
        }
    }
    return 0;
}

然后是用线段树的做法:
  难点在于区间的合并,要用线段树来维护三个变量,一个是每个区间的最长连续长度,二是区间最左端的最长长度,三是区间最右端的最长长度。
区间合并时:
= m a x { , } 区间的最长长度=max \lbrace左右区间各自的最长长度,合并后中间可能产生的新的长度 \rbrace =max{,}

区间最左端的最长连续长度=
左边区间的最左端长度+(左边区间的最左端长度==左边区间长度?右边区间的最左端长度:0)

区间的最右端的最长连续长度同理。
然后是查询,具体见代码。

#include <bits/stdc++.h>
using namespace std;
const int N=5e4+5;
struct node
{
    int left,len,right;
}tree[N<<2];
int a[N];
int n,m;
void pushup(int l,int r,int rt)//重点
{
    int mid=(l+r)>>1;
    tree[rt].len=max(max(tree[rt<<1].len,tree[rt<<1|1].len),tree[rt<<1].right+tree[rt<<1|1].left);
    if(tree[rt<<1].left==mid-l+1)
        tree[rt].left=tree[rt<<1].left+tree[rt<<1|1].left;
    else
        tree[rt].left=tree[rt<<1].left;
    if(tree[rt<<1|1].right==r-mid)
        tree[rt].right=tree[rt<<1].right+tree[rt<<1|1].right;
    else
        tree[rt].right=tree[rt<<1|1].right;
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        tree[rt].left=1;
        tree[rt].right=1;
        tree[rt].len=1;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(l,r,rt);
}
void update(int l,int r,int pos,int val,int rt)
{
    if(l==r)
    {
        tree[rt].len=val;
        tree[rt].left=val;
        tree[rt].right=val;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
        update(l,mid,pos,val,rt<<1);
    else
        update(mid+1,r,pos,val,rt<<1|1);
    pushup(l,r,rt);
}
int query(int l,int r,int pos,int rt)
{
    if(tree[rt].len==r-l+1||tree[rt].len==0)
        return tree[rt].len;
    int mid=(l+r)>>1;
    if(pos<=mid)//查询方法
        return pos>mid-tree[rt<<1].right?tree[rt<<1].right+tree[rt<<1|1].left:query(l,mid,pos,rt<<1);
    else
        return pos<=mid+tree[rt<<1|1].left?tree[rt<<1].right+tree[rt<<1|1].left:query(mid+1,r,pos,rt<<1|1);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int cnt=0,p;
        build(1,n,1);
        char ss[5]={0};
        for(int i=1;i<=m;i++)
        {
            scanf("%s",ss);
            if(ss[0]=='D')
            {
                scanf("%d",&p);
                a[++cnt]=p;
                update(1,n,p,0,1);
            }
            else if(ss[0]=='Q')
            {
                scanf("%d",&p);//cout<<"p = "<<p<<endl;
                printf("%d\n",query(1,n,p,1));
            }
            else if(ss[0]=='R')
            {
                if(cnt>0)
                    update(1,n,a[cnt--],1,1);
            }
        }
    }
    return 0;
}