HDU 1540 Tunnel Warfare 线段树区间合并

时间:2021-07-22 21:58:23

Tunnel Warfare

题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少

思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区间,左儿子的最大连续右区间+右儿子的最大连续左区间)决定

所以线段树的节点应该维护当前节点的最大连续左区间,最大连续右区间,和最大连续区间。

注意更新的时候,如果左儿子全满,父亲节点的左连续区间还要加上右儿子的左区间。反之同理。

查询的时候,可以剪枝,如果是叶子,或为空,或满,则不用往下查询。

查询的时候还要注意,当前查询点在左儿子的最大右连续区间内时,最大连续区间还要加上右儿子的最大连续区间。反之同理;

 // #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <string>
#include <algorithm>
#include <list>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
// #include <conio.h>
using namespace std;
#define clc(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int N = ;
const int MOD = 1e9+;
#define LL long long
#define mi() (l+r)>>1
double const pi = acos(-);
void fre() {
freopen("in.txt","r",stdin);
}
// inline int r() {
// int x=0,f=1;char ch=getchar();
// while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
// while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f;
// }
int s[N];
struct node {
int l,r;
int ls,rs,ms;
} e[N<<]; void pushup(int rt) { }
void build(int l,int r,int rt) {
e[rt].l=l;
e[rt].r=r;
e[rt].ls=e[rt].rs=e[rt].ms=r-l+;
if(l!=r) {
int mid=mi();
build(lson);
build(rson);
}
} void update(int rt,int c,int x) {
if(e[rt].l==e[rt].r) {
if(x>) {
e[rt].ls=e[rt].rs=e[rt].ms=;
} else
e[rt].ls=e[rt].rs=e[rt].ms=;
return;
}
int mid=(e[rt].l+e[rt].r)>>;
if(c<=mid) {
update(rt<<,c,x);
} else
update(rt<<|,c,x);
e[rt].ls=e[rt<<].ls;
e[rt].rs=e[rt<<|].rs;
e[rt].ms=max(max(e[rt<<].ms,e[rt<<|].ms),e[rt<<].rs+e[rt<<|].ls);
if(e[rt<<].ls==e[rt<<].r-e[rt<<].l+) {
e[rt].ls+=e[rt<<|].ls;
}
if(e[rt<<|].rs==e[rt<<|].r-e[rt<<|].l+) {
e[rt].rs+=e[rt<<].rs;
}
} int query(int rt,int c) {
if(e[rt].l==e[rt].r||e[rt].ms==||e[rt].ms==e[rt].r-e[rt].l+) {
return e[rt].ms;
}
int mid=(e[rt].l+e[rt].r)>>;
if(c<=mid) {
if(c>=e[rt<<].r-e[rt<<].rs+) {
return query(rt<<,c)+query(rt<<|,mid+);
} else
return query(rt<<,c);
} else {
if(c<=e[rt<<|].l+e[rt<<|].ls-) {
return query(rt<<|,c)+query(rt<<,mid);
} else
return query(rt<<|,c);
}
}
int main() {
// fre();
int n,q,top;
while(~scanf("%d%d",&n,&q)) {
build(,n,);
top=;
while(q--) {
char c;
int x;
cin>>c;
if(c=='D') {
cin>>x;
s[top++]=x;
update(,x,);
} else if(c=='Q') {
cin>>x;
printf("%d\n",query(,x));
} else {
x=s[--top];
update(,x,);
}
}
}
return ;
}