hdu1540 Tunnel Warfare
传送门
题意
有(n(nleq 50000))个点连成一条线,进行(m)次操作,操作共有三种:
1.毁掉一个点
2.查询与某点连续的点的数量
3.重建上一个被毁掉的点
计算每次查询操作的值
题解
线段树区间合并
每个元素内设三个变量:从区间左端点开始的最长连续点的个数(lmx),从区间右端点开始的最长连续点的个数(rmx),区间内最长连续点的个数(amx)
更新操作直接更新到对应点,之后向上合并
查询操作查询区间内包含某个点的连续的点的个数。如果当前点在左区间的(rmx)之内,则需要加上右区间的(lmx)。同理,如果当前点在右区间的(lmx)之内,则需要加上左区间的(rmx)
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=50010;
int n,m;
char s[5];
stack<int> stk;
struct node{
int lmx,rmx,amx;
}tree[4*maxn];
void pushup(int o,int l,int r){
int mid=(l+r)>>1;
tree[o].lmx=tree[o<<1].lmx;
if(tree[o<<1].lmx==mid-l+1) tree[o].lmx+=tree[o<<1|1].lmx;
tree[o].rmx=tree[o<<1|1].rmx;
if(tree[o<<1|1].rmx==r-mid) tree[o].rmx+=tree[o<<1].rmx;
tree[o].amx=max(max(tree[o<<1].amx,tree[o<<1|1].amx),tree[o<<1].rmx+tree[o<<1|1].lmx);
}
void build(int o,int l,int r){
if(l==r){
tree[o].lmx=tree[o].rmx=tree[o].amx=1;
return;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
pushup(o,l,r);
}
void change(int o,int l,int r,int x,int v){
if(l==r){
tree[o].lmx=tree[o].rmx=tree[o].amx=v;
return;
}
int mid=(l+r)>>1;
if(x<=mid) change(o<<1,l,mid,x,v);
else change(o<<1|1,mid+1,r,x,v);
pushup(o,l,r);
}
int query(int o,int l,int r,int x){
if(l==r || tree[o].amx==0 || tree[o].amx==r-l+1) return tree[o].amx;
int mid=(l+r)>>1;
int ans;
if(x<=mid){
if(x>=mid-tree[o<<1].rmx+1) ans=query(o<<1,l,mid,x)+query(o<<1|1,mid+1,r,mid+1);
else ans=query(o<<1,l,mid,x);
}
else{
if(x<=mid+tree[o<<1|1].lmx) ans=query(o<<1|1,mid+1,r,x)+query(o<<1,l,mid,mid);
else ans=query(o<<1|1,mid+1,r,x);
}
return ans;
}
int main(){
while(~scanf("%d %d",&n,&m)){
build(1,1,n);
while(!stk.empty()) stk.pop();
while(m--){
scanf("%s",s);
if(s[0]=='D'){
int x;
scanf("%d",&x);
change(1,1,n,x,0);
stk.push(x);
}
else if(s[0]=='Q'){
int x;
scanf("%d",&x);
printf("%d
",query(1,1,n,x));
}
else{
int x;
x=stk.top();
stk.pop();
change(1,1,n,x,1);
}
}
}
return 0;
}