线段树上找答案
线段树上找答案
题目来源 Problem - 1540 (hdu.edu.cn)

#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn = 1e6 + 10;
struct sgt_tree
{
#define ls (u<<1)
#define rs (u<<1|1)
int f[maxn << 2], lmx[maxn << 2], rmx[maxn << 2];
void upd(int l, int r, int u)
{
int mid = (l + r) >> 1;
if (f[ls] == mid - l + 1)lmx[u] = f[ls] + lmx[rs];
else lmx[u] = lmx[ls];
if (f[rs] == r - mid)rmx[u] = f[rs] + rmx[ls];
else rmx[u] = rmx[rs];
f[u] = max(max(f[ls], f[rs]), rmx[ls] + lmx[rs]);
}
void modify(int pos, int v, int l, int r, int u)
{
if (l == r) {
lmx[u] = rmx[u] = f[u] = v;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid)modify(pos, v, l, mid, ls);
else modify(pos, v, mid + 1, r, rs);
upd(l, r, u);
}
int findans(int k, int l, int r, int u)
{
if (l == r)return f[u];
int mid = (l + r) >> 1;
if (k <= mid) {
if (mid - rmx[ls] + 1 <= k)return rmx[ls] + lmx[rs];
else return findans(k, l, mid, ls);
}
else{
if (k <= mid + lmx[rs])return rmx[ls] + lmx[rs];
else return findans(k, mid + 1, r, rs);
}
}
void build(int l, int r, int u)
{
if (l == r) {
lmx[u] = rmx[u] = f[u] = 1;
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
upd(l, r, u);
}
#undef ls
#undef rs
}sgt;
int n, m;
int main()
{
while (~scanf("%d%d", &n, &m))
{
char op[3];
sgt.build(1, n, 1);
//cout << "dfs " << sgt.findans(1, 1, n, 1) << endl;
stack<int> st;
int x;
while (m--)
{
scanf("%s", op);
if (*op == 'D') {
scanf("%d", &x);
sgt.modify(x, 0, 1, n, 1);
st.push(x);
}
else if (*op == 'Q') {
scanf("%d", &x);
printf("%d\n", sgt.findans(x, 1, n, 1));
}
else {
sgt.modify(st.top(), 1, 1, n, 1);
st.pop();
}
}
}
return 0;
}

浙公网安备 33010602011771号