POJ2892 Tunnel Warfare

来源:互联网 发布:淘宝店面设计 知乎 编辑:程序博客网 时间:2024/05/17 18:13
/*查询包含当前点在内的最长连续子段思路:在左边找最大破坏点,右边找最小破坏点,相减后减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;}
原创粉丝点击