链接:http://poj.org/problem?id=2892
题意:有n个村庄排成一排,三种操作:
1. D x 摧毁村庄x
2. Q x 询问村庄x的最长一段没有被摧毁的村庄数量
3. R 恢复上一个被摧毁的村庄
思路:线段树区间合并,lsum记录当前节点往左的最长连续距离,rsum记录当前节点往右的最长连续距离。
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 50100
#define eps 1e-7
#define INF 0x3F3F3F3F //0x7FFFFFFF
#define LLINF 0x3F3F3F3F3F3F3F3F //0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[MAXN << 2], lsum[MAXN << 2], rsum[MAXN << 2];
int num[MAXN];
int n;
void pushup(int rt, int m){
lsum[rt] = lsum[rt << 1];
rsum[rt] = rsum[rt << 1 | 1];
if(lsum[rt] == (m - (m >> 1))) lsum[rt] += lsum[rt << 1 | 1];
if(rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt << 1];
sum[rt] = max(lsum[rt << 1 | 1] + rsum[rt << 1], max(sum[rt << 1], sum[rt << 1 | 1]));
}
void build(int l, int r, int rt){
sum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
if(l == r) return ;
int m = (l + r) >> 1;
build(lson);
build(rson);
}
void update(int k, int c, int l, int r, int rt){
if(l == r){
sum[rt] = lsum[rt] = rsum[rt] = c;
return ;
}
int m = (l + r) >> 1;
if(k <= m) update(k, c, lson);
else update(k, c, rson);
pushup(rt, r - l + 1);
}
int query(int pos, int l, int r, int rt){
if(l == r) return sum[rt];
int m = (l + r) >> 1;
if(m >= pos){
if(pos >= m - rsum[rt << 1] + 1) return lsum[rt << 1 | 1] + rsum[rt << 1];
else return query(pos, lson);
}
else{
if(pos <= m + lsum[rt << 1 | 1] + 1) return lsum[rt << 1 | 1] + rsum[rt << 1];
else return query(pos, rson);
}
}
stack<int>s;
int main(){
int i, j, m, c;
char str[5];
while(scanf("%d%d", &n, &m) != EOF){
build(1, n, 1);
while(!s.empty()) s.pop();
memset(num, 0, sizeof(int) * (n + 5));
while(m--){
scanf("%s", str);
if(str[0] == 'R'){
if(!s.empty()){
c = s.top();
s.pop();
num[c]--;
if(num[c] == 0) update(c, 1, 1, n, 1);
}
}
else{
scanf("%d", &c);
if(str[0] == 'D'){
if(num[c] == 0) update(c, 0, 1, n, 1);
num[c]++;
s.push(c);
}
else{
if(num[c]){
puts("0");
continue;
}
printf("%d\n", query(c, 1, n, 1));
}
}
}
}
return 0;
}