HDU 1540 Tunnel Warfare
2015-04-05 15:03
169 查看
这题是数据结构题,用线段树做,设置两个数组,记录节点最大左连续值,节点右最大连续值,输出便有三种情况,节点左最大连续值,节点右最大连续值,和兄弟节点之间左右最大连续值相加,注意,此题有个坑,坑了我好久,输入时不止一组数据,要用while(!=EOF)来写.
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #define maxn 50000 #define mem(a) memset(a, 0, sizeof(a)) using namespace std; long lv[maxn * 4 + 5], rv[maxn * 4 + 5], nl[maxn * 4 + 5], nr[maxn * 4 + 5], flag, num; void build(long l, long r, long n) { nl = l; nr = r; if(l == r) { lv = 1; rv = 1; return; } long mid = (l + r) / 2; build(l, mid, n * 2); build(mid + 1, r, n * 2 + 1); rv = lv = lv[n * 2] + lv[n * 2 + 1]; } void des(long l, long r, long n, long ll) { if(l == r&&l == ll) { lv = 0; rv = 0; return; } long mid = (l + r) / 2; if(ll <= mid) des(l, mid, n * 2, ll); else des(mid + 1, r, n * 2 + 1, ll); if(rv[n * 2 + 1] == lv[n * 2 + 1]&&rv[n * 2 + 1] == (nr[n * 2 + 1] - nl[n * 2 + 1] + 1)) rv = rv[n * 2 + 1] + rv[n * 2]; else rv = rv[n * 2 + 1]; if(rv[n * 2] == lv[n * 2]&&rv[n * 2] == (nr[n * 2] - nl[n * 2] + 1)) lv = lv[n * 2] + lv[n * 2 + 1]; else lv = lv[n * 2]; } void rbt(long l, long r, long n, long ll) { if(l == r&&l == ll) { lv = 1; rv = 1; return; } long mid = (l + r) / 2; if(ll <= mid) rbt(l, mid, n * 2, ll); else rbt(mid + 1, r, n * 2 + 1, ll); if(rv[n * 2 + 1] == lv[n * 2 + 1]&&rv[n * 2 + 1] == (nr[n * 2 + 1] - nl[n * 2 + 1] + 1)) rv = rv[n * 2 + 1] + rv[n * 2]; else rv = rv[n * 2 + 1]; if(rv[n * 2] == lv[n * 2]&&rv[n * 2] == (nr[n * 2] - nl[n * 2] + 1)) lv = lv[n * 2] + lv[n * 2 + 1]; else lv = lv[n * 2]; } void que(long l, long r, long n, long ll) { if(flag == 1) return; if((lv + nl - 1) >= ll) { if(l != 1&&rv[n - 1]) { printf("%ld\n",lv + rv[n - 1]); flag = 1; return; } printf("%ld\n", lv ); flag = 1; return; } if((nr - rv + 1) <= ll) { if(r != num&&lv[n + 1]) { printf("%ld\n",rv + lv[n + 1]); flag = 1; return; } printf("%ld\n",rv ); flag = 1; return; } if(l == r) return; long mid = (l + r) / 2; if(ll <= mid) que(l, mid, n * 2, ll); else que(mid + 1, r, n * 2 + 1, ll); } int main(int argc, char *argv[]) { int i, j; long q, a; char ch; stack<long> st; while(scanf("%ld%ld%*c", &num, &q) != EOF) { mem(lv); mem(rv); mem(nl); mem(nr); while(!st.empty()) { st.pop(); } build(1, num, 1); for(i = 0;i < q;i++) { scanf("%c", &ch); if(ch == 'D') { scanf("%ld%*c", &a); des(1, num, 1, a); st.push(a); } else if(ch == 'Q') { flag = 0; scanf("%ld%*c", &a); que(1, num, 1, a); if(!flag) printf("0\n"); } else if(ch == 'R') { scanf("%*c"); a = st.top(); st.pop(); rbt(1, num, 1, a); } } } return 0; }
相关文章推荐
- poj 2892 &&hdu 1540 Tunnel Warfare
- hdu 1540 Tunnel Warfare
- hdu 1540 Tunnel Warfare 线段树
- hdu 1540 Tunnel Warfare(线段树单点更新+区间合并)
- HDU 1540 Tunnel Warfare(单点更新,区间合并)
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
- 文章标题 HDU 1540 : Tunnel Warfare (线段树+最大连续区间)
- HDU - 1540 Tunnel Warfare(线段树 区间合并)
- HDU 1540 Tunnel Warfare
- HDU 1540 Tunnel Warfare
- HDU 1540 Tunnel Warfare(最长连续区间 基础)
- 【Hdu】1540 Tunnel Warfare(线段树|区间合并)
- HDU 1540 Tunnel Warfare
- 【38.96%】【hdu 1540】Tunnel Warfare
- HDU 1540 Tunnel Warfare
- HDU 1540 Tunnel Warfare(线段树)
- HDU 1540 Tunnel Warfare(set容器)
- HDU 1540 Tunnel Warfare(最长连续区间 基础)
- I - Tunnel Warfare - hdu 1540(区间合并更新)
- HDU 1540 Tunnel Warfare 【线段树 + 思维】