题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1540
题意:
给你一个区间,有三个操作,使的一个村庄毁灭,使的上一个毁灭的村庄复活,查询这个村庄所在最长区间
题解:
区间合并的线段树,单点修改,记录从左边的最大值,右边的最大值,区间的最大值
然后每次更新
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//////////////////////////////////////////////////////////////////////////
const int maxn = 1e5+10;
struct node{
int l,r,lm,rm,mm,len;
}tree[maxn<<2];
void pushup(int rt){
tree[rt].lm = tree[rt<<1].lm;
tree[rt].rm = tree[rt<<1|1].rm;
tree[rt].mm = max(max(tree[rt<<1].mm,tree[rt<<1|1].mm),tree[rt<<1].rm+tree[rt<<1|1].lm);
if(tree[rt<<1].lm == tree[rt<<1].len) tree[rt].lm = tree[rt<<1].lm + tree[rt<<1|1].lm;
if(tree[rt<<1|1].rm == tree[rt<<1|1].len) tree[rt].rm = tree[rt<<1].rm+tree[rt<<1|1].rm;
}
void build(int rt,int l,int r){
tree[rt].l = l, tree[rt].r = r;
tree[rt].lm = tree[rt].rm = tree[rt].mm = tree[rt].len = r-l+1;
if(l != r){
int mid = (l+r)/2;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
}
void update(int rt,int p,int x){
int L = tree[rt].l, R = tree[rt].r;
if(L == R) {
tree[rt].lm=tree[rt].rm=tree[rt].mm = x;
return ;
}
int mid = (L+R)/2;
if(p <= mid) update(rt<<1,p,x);
else update(rt<<1|1,p,x);
pushup(rt);
}
ll query(int rt,int p){
int L = tree[rt].l, R = tree[rt].r;
if(L==R || tree[rt].mm==0 || tree[rt].mm==tree[rt].len)
return tree[rt].mm;
int mid = (L+R)/2;
if(p<=mid){
if(p >= tree[rt<<1].r - tree[rt<<1].rm + 1){
return query(rt<<1,p) + query(rt<<1|1,mid+1);
}else{
return query(rt<<1,p);
}
}else{
if(p <= tree[rt<<1|1].l+tree[rt<<1|1].lm-1){
return query(rt<<1|1,p) + query(rt<<1,mid);
}else{
return query(rt<<1|1,p);
}
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
stack<int> k;
build(1,1,n);
for(int i=0; i<m; i++){
char op; scanf(" %c",&op);
int t;
if(op == 'D'){
scanf("%d",&t);
update(1,t,0);
k.push(t);
}else if(op == 'Q'){
scanf("%d",&t);
printf("%I64d\n",query(1,t));
}else{
update(1,k.top(),1);
k.pop();
}
}
}
return 0;
}