HDU 1540 Tunnel Warfare(线段树区间合并)

来源:互联网 发布:中国网络小说家排行榜 编辑:程序博客网 时间:2024/05/21 09:37

题意:

题目定义了3种操作
D代表破坏村庄,
R代表修复最后被破坏的那个村庄,
Q代表询问包括x在内的最大连续区间是多少

思路:

和前面几道线段树的区间合并一样,在线段树的区间内,我们要用三个变量记录左边连续区间,右边连续区间和最大连续区间。
这题主要的难点是怎么查询。
我的查询函数是这么写的。

int query(int o, int L, int R, int pos) {    if(L == R) return 0;    int M = MID;    pushDown(o, L, R);    if(M - mxR[ls] + 1 <= pos && pos <= M + mxL[rs])        return mxR[ls] + mxL[rs];     else if(pos <= M) return query(lson, pos);    else return query(rson, pos);}

判断当前的位置是否满足在左边连续和右边连续的区间之内。
如果满足返回当前该区间的长度,否则向下查找。

my code

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define MID (L + R) >> 1#define ls (o<<1)#define rs (o<<1|1)#define lson ls, L, M#define rson rs, M+1, R#define LEN(L, R) ((R) - (L) + 1)using namespace std;const int N = (int)5e4 + 10;int n, m;int mxL[N<<2], mxR[N<<2], mx[N<<2], cov[N<<2];vector<int> vec;int max(int a, int b, int c) {    return max(a, max(b, c));}void pushUp(int o, int L, int R) {    int M = MID;    mxL[o] = mxL[ls], mxR[o] = mxR[rs];    mx[o] = max(mx[ls], mx[rs], mxR[ls] + mxL[rs]);    if(mxL[ls] == LEN(L, M)) mxL[o] += mxL[rs];    if(mxR[rs] == LEN(M+1, R)) mxR[o] += mxR[ls];    if(cov[ls] == cov[rs]) cov[o] = cov[ls];    else cov[o] = -1;}void pushDown(int o, int L, int R) {    if(cov[o] != -1) {        int M = MID;        cov[ls] = cov[rs] = cov[o];        mxL[ls] = mxR[ls] = mx[ls] = cov[o] * LEN(L, M);        mxL[rs] = mxR[rs] = mx[rs] = cov[o] * LEN(M+1, R);        cov[o] = -1;    }}void build(int o, int L, int R) {    cov[o] = -1;    if(L == R) {        mxL[o] = mxR[o] = mx[o] = cov[o] = 1;        return ;    }    int M = MID;    build(lson);    build(rson);    pushUp(o, L, R);}void modify(int o, int L, int R, int pos, int val) {    if(L == R) {        mxL[o] = mxR[o] = mx[o] = cov[o] = val;        return ;    }    int M = MID;    pushDown(o, L, R);    if(pos <= M) modify(lson, pos, val);    else modify(rson, pos, val);    pushUp(o, L, R);}int query(int o, int L, int R, int pos) {    if(L == R) return 0;    int M = MID;    pushDown(o, L, R);    if(M - mxR[ls] + 1 <= pos && pos <= M + mxL[rs])        return mxR[ls] + mxL[rs];     else if(pos <= M) return query(lson, pos);    else return query(rson, pos);}int main() {    char op[10];    int ql, qr, x;    while(~scanf("%d%d", &n, &m)) {        build(1, 1, n);        vec.clear();        while(m--) {            scanf("%s", op);            if(op[0] == 'D') {                scanf("%d", &x);                vec.push_back(x);                modify(1, 1, n, x, 0);            }else if(op[0] == 'Q') {                scanf("%d", &x);                int ans = query(1, 1, n, x);                printf("%d\n", ans);            }else if(op[0] == 'R') {                x = vec.back();                vec.pop_back();                modify(1, 1, n, x, 1);            }        }    }    return 0;}
0 0