基础线段树区间合并,详见代码
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 500010;
stack < int > s;
int n, m;
struct node{
int l, r;
int ls, rs;
}tr[N << 2];
void build( int l, int r, int rt )
{
tr[rt].l = l;
tr[rt].r = r;
tr[rt].ls = tr[rt].rs = ( r - l + 1 );
if( l == r )
return;
int mid = (l + r) >> 1;
build( lson );
build( rson );
}
void pushup( int rt )
{
tr[rt].ls = tr[rt << 1].ls;
tr[rt].rs = tr[rt << 1 | 1].rs;
//如果左子树全为1,那么左子树长度要加上右子树的左边(下面也为同理)
if( tr[rt << 1].ls == tr[rt << 1].r - tr[rt << 1].l + 1 )
tr[rt].ls += tr[rt << 1 | 1].ls;
if( tr[rt << 1 | 1].rs == tr[rt << 1 | 1].r - tr[rt << 1 | 1].l + 1 )
tr[rt].rs += tr[rt << 1].rs;
}
void update( int pos, int sta, int rt )
{
//单点更新
if( tr[rt].l == tr[rt].r )
{
tr[rt].ls = tr[rt].rs = sta;
return;
}
int mid = ( tr[rt].l + tr[rt].r ) >> 1;
if( pos <= mid )
update( pos, sta, rt << 1 );
else
update( pos, sta, rt << 1 | 1 );
//回溯
pushup( rt );
}
int query( int pos, int rt )
{
//单点查询
if( tr[rt].l == tr[rt].r )
return tr[rt].ls;
int mid = ( tr[rt].l + tr[rt].r ) >> 1;
if( pos <= mid )
{
//查询位置在左子树的右边,则要加上右子树的左边,(下面同理)
if( pos >= mid - tr[rt << 1].rs + 1 )
return tr[rt << 1].rs + tr[rt << 1 | 1].ls;
return query( pos, rt << 1 );
}
else
{
if( pos <= mid + tr[rt << 1 | 1].ls )
return tr[rt << 1].rs + tr[rt << 1 | 1].ls;
return query( pos, rt << 1 | 1 );
}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
build( 1, n, 1 );
while( !s.empty() )
s.pop();
while( m-- )
{
int a;
char op[10];
scanf("%s", op);
if( op[0] == 'R' )
{
if( s.empty() )
continue;
else
{
update( s.top(), 1, 1 );
s.pop();
}
}
else
{
scanf("%d", &a);
if( op[0] == 'D' )
{
update( a, 0, 1 );
s.push(a);
}
else
{
int ans = query( a, 1 );
printf("%d\n", ans);
}
}
}
}
return 0;
}