POJ2892 Tunnel Warfare

/*查询包含当前点在内的最长连续子段思路:在左边找最大破坏点,右边找最小破坏点,相减后减1即可最开始写的递归线段树,挫了- -,而且还完全想不通,赶脚不会爱了。于是用zkw线段树自底向顶搞,AC了。传说有区间合并做法,费时费力,不写了留待有缘人哈哈。。*/#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int MAXN = 50001;const int INF = ~0u>>1;int tmax[MAXN<<2],tmin[MAXN<<2];int M,n;int D[MAXN],p;int max(int a, int b) { return a>b?a:b; }int min(int a, int b) { return a<b?a:b; }void update(int pos, int num){pos += M;if(num != -1) tmax[pos] = tmin[pos] = num;else{tmax[pos] = 0;tmin[pos] = n+1;}for(pos>>=1; pos; pos>>=1){tmax[pos] = max(tmax[pos<<1], tmax[pos<<1|1]);tmin[pos] = min(tmin[pos<<1], tmin[pos<<1|1]);}}int Rquery(int L){int R = n+1+M;L += M;int ans = n+1;for(; L^R^1; L>>=1,R>>=1){if(~L&1) ans = min(ans, tmin[L^1]);if( R&1) ans = min(ans, tmin[R^1]);}return ans;}int Lquery(int R){int L = M;R += M;int ans = 0;for(; L^R^1; L>>=1,R>>=1){if(~L&1) ans = max(ans, tmax[L^1]);if( R&1) ans = max(ans, tmax[R^1]);}return ans;}int main(){int q;char op[3];int d;while(~scanf("%d%d", &n, &q)){for(M=1; M<n+2; M<<=1);for(int i=M+n; i>0; i--){tmax[i] = 0;tmin[i] = n+1;}p = 0;while(q--){scanf("%s%d", op, &d);if(op[0] == 'D'){update(d,d);D[++p] = d;}else if(op[0] == 'Q'){if(tmax[d+M] != 0) printf("0\n");else printf("%d\n", Rquery(d) - Lquery(d) - 1);}else{update(D[p],-1);p--;}}}return 0;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值