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;
}