#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4+50;
struct node
{
int l, r;
int ls, rs, ms;// 该区间 最左端最大连续区间, 最右端最大连续区间,该区间内最大区间
} Segtr[maxn*4];
stack<int>s;
void build(int rt,int L, int R)
{
Segtr[rt].l = L;
Segtr[rt].r = R;
Segtr[rt].ls = Segtr[rt].rs = Segtr[rt].ms = (R-L+1);
if(L == R)
{
return;
}
int mid = (L+R)/2;
build(rt*2+1, L, mid);
build(rt*2+2, mid+1, R);
}
void update(int rt, int x, int op)
{
if(Segtr[rt].l == Segtr[rt].r)
{
if(op == 1)//修复
Segtr[rt].ls = Segtr[rt].rs = Segtr[rt].ms = 1;
else
Segtr[rt].ls = Segtr[rt].rs = Segtr[rt].ms = 0;
return ;
}
int mid = (Segtr[rt].l +Segtr[rt].r)/2;
if(x <= mid)
{
update(rt*2+1, x, op);
}
else
{
update(rt*2+2, x, op);
}
Segtr[rt].ls = Segtr[rt*2+1].ls;
Segtr[rt].rs = Segtr[rt*2+2].rs;
Segtr[rt].ms = max(max(Segtr[2*rt+1].ms, Segtr[rt*2+2].ms), Segtr[rt*2+1].rs+Segtr[rt*2+2].ls);
if(Segtr[rt*2+1].ls == Segtr[rt*2+1].r- Segtr[rt*2+1].l+1)
{
Segtr[rt].ls +=Segtr[rt*2+2].ls;
}
if(Segtr[rt*2+2].rs == Segtr[rt*2+2].r - Segtr[rt*2+2].l +1)
{
Segtr[rt].rs += Segtr[rt*2+1].rs;
}
}
int query(int rt, int x)
{
int l = Segtr[rt].l;
int r = Segtr[rt].r;
//如果 查询的 节点所在的父区间 为 0 为 满 或者到达叶子节点 直接返回, 不在往下询问
if(Segtr[rt].l == Segtr[rt].r ||Segtr[rt].ms == 0|| Segtr[rt].r - Segtr[rt].l + 1== Segtr[rt].ms)
return Segtr[rt].ms;
int mid = (l + r)/2;
if(x <= mid)
{
if(x >= Segtr[rt*2+1].r - Segtr[rt*2+1].rs+1) // 判断要查询的是否 在 左节点右端最大连续区间内
{
return query(rt*2+1, x)+query(rt*2+2, mid+1);
}
else
{
return query(rt*2+1, x);
}
}
else
{
if( x<=Segtr[rt*2+2].l+Segtr[rt*2+2].ls-1 )// 判断要查询寻的节点是否在右节点左端最大连续区间内
{
return query(rt*2+1, mid)+ query(rt*2+2, x);
}
else return query(rt*2+2, x);
}
}
void init()
{
while(!s.empty())s.pop();
}
int main()
{
ios_base::sync_with_stdio(false);
int n, m;
char op;
int x;
while(cin>>n>>m)
{
init();
build(0, 1, n);
for(int i = 0;i < m;i++)
{
cin>>op;
if(op!= 'R')cin>>x;
if(op == 'D')
{
update(0 , x, 0);
s.push(x);
}
else if(op == 'Q')
{
int ans = query(0, x);
cout << ans<<endl;
}
else
{
int tp = s.top();
s.pop();
update(0, tp, 1);
}
}
}
return 0;
}
一个区间内的最大连续区间:
要么是左儿子的最大连续区间 , 要么是右儿子的最大连续区间 。
要么是做儿子右端区间+ 右儿子左端区间。