HDU 1540 Tunnel Warfare 线段树区间合并

Tunnel Warfare

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

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

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

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

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

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

  1 // #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <sstream>
  6 #include <string>
  7 #include <algorithm>
  8 #include <list>
  9 #include <map>
 10 #include <vector>
 11 #include <queue>
 12 #include <stack>
 13 #include <cmath>
 14 #include <cstdlib>
 15 // #include <conio.h>
 16 using namespace std;
 17 #define clc(a,b) memset(a,b,sizeof(a))
 18 #define inf 0x3f3f3f3f
 19 #define lson l,mid,rt<<1
 20 #define rson mid+1,r,rt<<1|1
 21 const int N = 50010;
 22 const int MOD = 1e9+7;
 23 #define LL long long
 24 #define mi() (l+r)>>1
 25 double const pi = acos(-1);
 26 void fre() {
 27     freopen("in.txt","r",stdin);
 28 }
 29 // inline int r() {
 30 //     int x=0,f=1;char ch=getchar();
 31 //     while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
 32 //     while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f;
 33 // }
 34 int s[N];
 35 struct node {
 36     int l,r;
 37     int ls,rs,ms;
 38 } e[N<<2];
 39 
 40 void pushup(int rt) {
 41 
 42 }
 43 void build(int l,int r,int rt) {
 44     e[rt].l=l;
 45     e[rt].r=r;
 46     e[rt].ls=e[rt].rs=e[rt].ms=r-l+1;
 47     if(l!=r) {
 48         int mid=mi();
 49         build(lson);
 50         build(rson);
 51     }
 52 }
 53 
 54 void update(int rt,int c,int x) {
 55     if(e[rt].l==e[rt].r) {
 56         if(x>0) {
 57             e[rt].ls=e[rt].rs=e[rt].ms=1;
 58         } else
 59             e[rt].ls=e[rt].rs=e[rt].ms=0;
 60         return;
 61     }
 62     int mid=(e[rt].l+e[rt].r)>>1;
 63     if(c<=mid) {
 64         update(rt<<1,c,x);
 65     } else
 66         update(rt<<1|1,c,x);
 67     e[rt].ls=e[rt<<1].ls;
 68     e[rt].rs=e[rt<<1|1].rs;
 69     e[rt].ms=max(max(e[rt<<1].ms,e[rt<<1|1].ms),e[rt<<1].rs+e[rt<<1|1].ls);
 70     if(e[rt<<1].ls==e[rt<<1].r-e[rt<<1].l+1) {
 71         e[rt].ls+=e[rt<<1|1].ls;
 72     }
 73     if(e[rt<<1|1].rs==e[rt<<1|1].r-e[rt<<1|1].l+1) {
 74         e[rt].rs+=e[rt<<1].rs;
 75     }
 76 }
 77 
 78 int query(int rt,int c) {
 79     if(e[rt].l==e[rt].r||e[rt].ms==0||e[rt].ms==e[rt].r-e[rt].l+1) {
 80         return e[rt].ms;
 81     }
 82     int mid=(e[rt].l+e[rt].r)>>1;
 83     if(c<=mid) {
 84         if(c>=e[rt<<1].r-e[rt<<1].rs+1) {
 85             return query(rt<<1,c)+query(rt<<1|1,mid+1);
 86         } else
 87             return query(rt<<1,c);
 88     } else {
 89         if(c<=e[rt<<1|1].l+e[rt<<1|1].ls-1) {
 90             return query(rt<<1|1,c)+query(rt<<1,mid);
 91         } else
 92             return query(rt<<1|1,c);
 93     }
 94 }
 95 int main() {
 96 //    fre();
 97     int n,q,top;
 98     while(~scanf("%d%d",&n,&q)) {
 99         build(1,n,1);
100         top=0;
101         while(q--) {
102             char c;
103             int x;
104             cin>>c;
105             if(c=='D') {
106                 cin>>x;
107                 s[top++]=x;
108                 update(1,x,0);
109             } else if(c=='Q') {
110                 cin>>x;
111                 printf("%d\n",query(1,x));
112             } else {
113                 x=s[--top];
114                 update(1,x,1);
115             }
116         }
117     }
118     return 0;
119 }

 

转载于:https://www.cnblogs.com/ITUPC/p/5633982.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值