HDOJ1540地道战

发布时间:2022-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了HDOJ1540地道战脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

地道战

HDOJ1540地道战

思路:

题目可以转化为,求包含x的最长连续子段 使用线段树合并,因为线段树的左右区间是相邻的 分别维护一个左前缀和右后缀的最大长度

代码:

#include <bITs/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline 'n'
const int N = 500010;
struct T {
    int l, r, lmax, rmax;
    int val;
} tr[N << 2];
void pushup(int p) {
    tr[p].lmax = tr[p << 1].lmax;
    tr[p].rmax = tr[p << 1 | 1].rmax;
    if (tr[p << 1].lmax == tr[p << 1].r - tr[p << 1].l + 1) tr[p].lmax = tr[p << 1].lmax + tr[p << 1 | 1].lmax;//如果左边全是,那父节点就是左边全部+右边左前缀
    if (tr[p << 1 | 1].rmax == tr[p << 1 | 1].r - tr[p << 1 | 1].l + 1) tr[p].rmax = tr[p << 1 | 1].rmax + tr[p << 1].rmax;//同理
}
void build(int p, int l, int r) {
    if (l == r) {
        tr[p] = {l, r, 1, 1, 1};
        return;
    }
    tr[p] = {l, r};
    int mid = l + r >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    pushup(p);
}
int query(int p, int x) {
    if (tr[p].lmax == tr[p].r - tr[p].l + 1 or tr[p].l == tr[p].r) {
        return tr[p].lmax;
    }
    int mid = tr[p].l + tr[p].r >> 1;
    if (x <= mid) {//如果当前x到mid的长度小于等于左区间的右前缀,答案就是左区间右前缀+右区间左前缀,ps:不用考虑左区间左边的区间,因为第一次len<rmax就会返回
        if (mid - x + 1 <= tr[p << 1].rmax) {
            return tr[p << 1].rmax + tr[p << 1 | 1].lmax;
        } else {
            return query(p << 1, x);
        }
    } else if (x > mid) {
        if (x - mid <= tr[p << 1 | 1].lmax) {
            return tr[p << 1 | 1].lmax + tr[p << 1].rmax;
        } else {
            return query(p << 1|1, x);
        }
    }
}
void modify(int p, int x, int v) {
    if (tr[p].l == x and tr[p].r == x) {
        tr[p] . val = tr[p].lmax = tr[p].rmax = v;
        return;
    }
    int mid = tr[p].l + tr[p].r >> 1;
    if (x <= mid) modify(p << 1, x, v);
    else modify(p << 1 | 1, x, v);
    pushup(p);
}

void solve(int Case) {
    int n, m;
    while (cin >> n >> m) {
        build(1, 1, n);
        stack<int> stk;
        for (; m--;) {
            string op;
            int x;
            cin >> op;
            if (op == "D") {
                cin >> x;
                modify(1, x, 0);
                stk.push(x);
            } else if (op == "Q") {
                cin >> x;
                cout << query(1, x) << nline;
            } else {
                if (stk.size()) {
                    auto t = stk.top();
                    stk.pop();
                    modify(1, t, 1);
                }
            }
        }
    }
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
//   for (cin >> _, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}

脚本宝典总结

以上是脚本宝典为你收集整理的HDOJ1540地道战全部内容,希望文章能够帮你解决HDOJ1540地道战所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。