题目意思
n个点,m个操作(1<=n,m<=5e4),m行中每行一个字符表示操作类型,一个整型数x表示第x个点
D x 表示去掉第x点,Q x表示需输出含 x 的最大连续区间的长度,R x表示还原最后去掉的点
解析:
看到区间查询和修改很明显是线段树
#include<iostream>
#include<string>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
int lx,rx,mx;
}a[50005<<4];
void build(int l,int r,int rt){
a[rt].lx=a[rt].mx=a[rt].rx=r-l+1;
if(l==r)return;
build(l,(l+r)/2,rt*2);
build((l+r)/2+1,r,rt*2+1);
}
void update(int rt,int l,int r,int c,int x){
if(x<l||x>r)return;
if(l==r){
a[rt].lx=a[rt].mx=a[rt].rx=c;
return;
}
update(rt*2,l,(l+r)/2,c,x);
update(rt*2+1,(l+r)/2+1,r,c,x);
a[rt].mx=max(max(a[rt*2].mx,a[rt*2+1].mx),a[rt*2].rx+a[rt*2+1].lx);
a[rt].lx=a[rt*2].lx;
if(a[rt*2].lx==(r+l)/2-l+1)a[rt].lx+=a[rt*2+1].lx;
a[rt].rx=a[rt*2+1].rx;
if(a[rt*2+1].rx==r-(r+l)/2)a[rt].rx+=a[rt*2].rx;
}
int query(int x,int l,int r,int rt){
if(l==r||a[rt].mx==r-l+1||a[rt].mx==0)return a[rt].mx;
if(x<(l+r)/2-a[rt*2].rx+1)return query(x,l,(l+r)/2,rt*2);
if(x>(l+r)/2+a[rt*2+1].lx)return query(x,(r+l)/2+1,r,rt*2+1);
return a[rt*2].rx+a[rt*2+1].lx;
}
int main()
{
int n,q,x;
while(cin>>n>>q){
stack<int> ls;
char s;
build(1,n,1);
for(int i=1;i<=q;i++){
cin>>s;
if(s=='D'){
cin>>x;
update(1,1,n,0,x);
ls.push(x);
}
else if(s=='R'){
int u=ls.top();ls.pop();
update(1,1,n,1,u);
}
else{
cin>>x;
cout<<query(x,1,n,1)<<endl;
}
}
}
return 0;
}