题目:http://acm.hdu.edu.cn/showproblem.php?pid=1540
题意:
开始都为,D为破坏一个村子,R为修复最后一个被破坏的村子,Q为查询包括该点的最长连续区间。
#include<bits/stdc++.h>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int maxn=1e5+10;
int n,m;
struct node{
int l,r;
int lsum; //从该点向左,共有lsum个连续区间
int rsum; //从该点向右,共有rsum个连续区间
int sum; //该点连续区间长度
}t[maxn<<2];
int lazy[maxn<<2];
stack <int> s;
void up(int rt,int l,int r){
t[rt].lsum=t[rt<<1].lsum;
t[rt].rsum=t[rt<<1|1].rsum;
int mid=(l+r)>>1;
if(t[rt].lsum==mid-l+1) t[rt].lsum+=t[rt<<1|1].lsum;
if(t[rt].rsum==r-mid ) t[rt].rsum+=t[rt<<1].rsum;
t[rt].sum=max(t[rt<<1].rsum+t[rt<<1|1].lsum,max(t[rt<<1].sum,t[rt<<1|1].sum));
}
void build(int rt,int l,int r){
t[rt].l=l,t[rt].r=r;
t[rt].sum=t[rt].lsum=t[rt].rsum=r-l+1;
if(l==r) return ;
int mid=(l+r)>>1;
build(lson),build(rson);
}
void update(int rt,int x,int k){ //1是破坏
if(t[rt].l==t[rt].r){
t[rt].sum=t[rt].lsum=t[rt].rsum=k;
return ;
}
int mid=(t[rt].l+t[rt].r)>>1;
if(x<=mid) update(rt<<1,x,k);
else update(rt<<1|1,x,k);
up(rt,t[rt].l,t[rt].r);
}
int query(int rt,int x){
if(t[rt].l==t[rt].r || t[rt].sum==0 || t[rt].sum==t[rt].r-t[rt].l+1)//叶子节点或者该访问区间为空或者已满
return t[rt].sum;
int mid=(t[rt].l+t[rt].r)>>1;
if(x<=mid){
if(x>=t[rt<<1].r-t[rt<<1].rsum+1)
return query(rt<<1,x)+query(rt<<1|1,mid+1);
else
return query(rt<<1,x);
}
else{
if(x<=t[rt<<1|1].l+t[rt<<1|1].lsum-1)
return query(rt<<1|1,x)+query(rt<<1,mid);
else
return query(rt<<1|1,x);
}
}
int main(){
while(cin>>n>>m){
build(1,1,n);
while(m--){
char ch;
int x;
cin>>ch;
if(ch=='D'){
cin>>x, s.push(x);
update(1,x,0);
}
else if(ch=='Q'){
cin>>x;
int ans=query(1,x);
printf("%d\n",ans);
}
else{
x=s.top(), s.pop();
update(1,x,1);
}
}
}
return 0;
}