iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。
iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。
用stl和线段树都写了一遍。难的地方在于寻找pos所在位置的连续块的长度。
/*
Pro: 0
Sol:
date:2012/09/24 19:14-
*/
//#include <iostream>
//#include <cstdio>
//#include <algorithm>
//#include <cstring>
//#include <cmath>
//#include <queue>
//#include <set>
//#include <vector>
//using namespace std;
//char op[10];
//int cnt ,m,n,x;
//set <int> mp;
//int stack[51000];
//int main(){
// while(scanf("%d%d",&n,&m) != EOF){
// mp.clear();
// mp.insert(0);
// mp.insert(n + 1);
// cnt = 0;
// for(int i = 0; i < m; i++){
// scanf("%s",op);
// if(op[0] != 'R') scanf("%d",&x);
// if(op[0] == 'D'){
// stack[cnt ++] = x;
// mp.insert(x);
// }else if(op[0] == 'Q'){
// if(*mp.lower_bound(x) == x)
// printf("0\n");
// else{
// set <int> :: iterator it;
// it = mp.lower_bound(x);
// printf("%d\n", *it - *(--it) - 1);
// }
// }else if(op[0] == 'R'){
// mp.erase(mp.find(stack[--cnt]));
// }
// }
// }
// return 0;
//}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#define maxn 50010
#define havem int m = (l + r) >> 1
#define lson l,m , rt << 1
#define rson m+ 1, r, rt << 1|1
#define ls rt << 1
#define rs rt << 1|1
using namespace std;
char op[10];
int cnt ,m,n,x,li,ri;
int stack[51000];
int lsum[maxn << 2], rsum[maxn << 2], msum[maxn << 2];
void build(int l,int r, int rt){
lsum[rt] = rsum[rt] = msum[rt] = r -l + 1;
if(l ==r) return ;
havem;
build(lson); build(rson);
}
void up(int rt, int m){
lsum[rt] = (lsum[ls] == m - (m >> 1)) ? lsum[ls] + lsum[rs] : lsum[ls];
rsum[rt] = (rsum[rs] == (m >> 1)) ? rsum[ls] + rsum[rs] : rsum[rs];
msum[rt] = max( max(msum[ls], msum[rs]), rsum[ls] + lsum[rs] );
}
void update(int pos, int val, int l, int r, int rt){
if(l == r){
lsum[rt] = rsum[rt] = msum[rt] = val;
return ;
}havem;
if(pos <= m) update(pos,val,lson);
else update(pos,val,rson);
up(rt, r - l + 1);
}
int query(int pos,int l, int r, int rt){//寻找pos所在位置的连续1的长度
if(msum[rt] == 0) return 0;
if(msum[rt] == r - l + 1) return msum[rt];
havem;//这个不要忘了。就因为这个调了10分钟。敲只敲了3分钟,当然是照着敲的
if(lsum[rt] && lsum[rt] + l - 1 >= pos) return lsum[rt];//左边
if(rsum[rt] && r - rsum[rt] + 1 <= pos) return rsum[rt];//右边
//中间的情况还要分批考虑,这是之前不会写的地方。导致下面的pos<= m都不会写了。
if(pos <= m && m - rsum[ls] + 1 <= pos && rsum[ls]) return lsum[rs] + rsum[ls];
if(pos > m && m + lsum[rs] >= pos && lsum[rs]) return lsum[rs] + rsum[ls];
if(pos <= m)
return query(pos,lson);
else
return query(pos,rson);
}
int main(){
while(scanf("%d%d",&n,&m) != EOF){
build(1,n,1); cnt = 0;
for(int i = 0; i < m; i++){
scanf("%s",op);
if(op[0] != 'R') scanf("%d",&x);
if(op[0] == 'D'){
update(x,0,1,n,1);
stack[cnt ++] = x;
}else if(op[0] == 'Q'){
int ans = query(x,1,n,1);
printf("%d\n",ans);
}else if(op[0] == 'R'){
update(stack[-- cnt], 1, 1,n,1);
}
}
}
return 0;
}