HDU 1540 Tunnel Warfare

有N个村庄,只要村庄没有被摧毁就可以相互联系,一个村庄可以通过村庄和其他村庄联系,敌人会摧毁某个特定的村庄,然后我放可以修复最近被摧毁的村庄,然后询问第k个村庄最多可以联系到几个村庄(包括自身)

求最大连续值问题,线段树维护区间最大连续长度,然后区间合并。

查询的时候累加左右两边的连续值即可,注意连续区间是否会断开。

比较坑人的是这题是多组数据。。而且每个村庄可以被多次摧毁,此时不用更新标记但是要更新栈。。就为了这两个问题WA了超多次。。

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 #define M ((L+R)>>1)
 5 #define lson rt<<1,L,M
 6 #define rson rt<<1|1,M+1,R
 7 #define len(a,b) ((b)-(a)+1)
 8 
 9 using namespace std;
10 
11 const int maxn = 500001;
12 
13 bool isdes[maxn],val;
14 int lmax[maxn<<2],rmax[maxn<<2],tar,desed[maxn],pd;
15 
16 inline void pushup(int rt,int L,int R) {
17     lmax[rt] = lmax[rt<<1];  rmax[rt] = rmax[rt<<1|1];
18     if(!isdes[M] && !isdes[M + 1]) {
19         if(lmax[rt<<1] == len(L,M)) lmax[rt] = lmax[rt<<1] + lmax[rt<<1|1];
20         if(rmax[rt<<1|1] == len(M + 1,R)) rmax[rt] = rmax[rt<<1|1] + rmax[rt<<1];
21     }
22 }
23 
24 void build(int rt,int L,int R) {
25     if(L == R) {
26         lmax[rt] = rmax[rt] = 1;
27         isdes[L] = false;
28     } else {
29         build(lson); build(rson);
30         lmax[rt] = rmax[rt] = lmax[rt<<1] + lmax[rt<<1|1];
31     }
32 }
33 
34 void update(int rt,int L,int R) {
35     if(L == R) {
36         isdes[L] = val;
37         lmax[rt] = rmax[rt] = (int)(!val);
38     } else {
39         if(tar <= M) update(lson);
40         else update(rson);
41         pushup(rt,L,R);
42     }
43 }
44 
45 int query(int t,int n) {
46     int L = 1,R = n,rt = 1,left = 0,right = 0;
47     if(isdes[t]) return 0;
48     while(1) {
49         if(L == R) return left + right + 1;
50         if(t <= M) {
51             if(lmax[rt<<1|1] == len(M + 1,R)) right += lmax[rt<<1|1];
52             else right = lmax[rt<<1|1];
53             rt = rt<<1; R = M;
54         } else {
55             if(rmax[rt<<1] == len(L,M)) left += rmax[rt<<1];
56             else left = rmax[rt<<1];
57             rt = rt<<1|1; L = M + 1;
58         }
59     }
60 }
61 
62 int main() {
63     int N,m;
64     char cmd;
65     while(scanf("%d%d",&N,&m) != EOF) {
66         memset(desed,0,sizeof(desed));
67         pd = 0;
68         build(1,1,N);
69         for(int c = 0;c < m;c++) {
70             scanf(" %c",&cmd);
71             if(cmd == 'R') {
72                 if(!pd) continue;
73                 while(pd && desed[pd - 1] == false) pd--;
74                 tar = desed[--pd];
75                 val = false;
76                 update(1,1,N);
77             } else {
78                 scanf("%d",&tar);
79                 if(cmd == 'D') {
80                     desed[pd++] = tar;
81                     if(isdes[tar]) continue;
82                     val = true;
83                     update(1,1,N);
84                 } else printf("%d\n",query(tar,N));
85             }
86         }
87     }
88     return 0;
89 }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值