线段树上找答案

线段树上找答案

题目来源 Problem - 1540 (hdu.edu.cn)

image

#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;
}
posted @ 2021-10-06 00:07  warmhearthhh  阅读(49)  评论(0)    收藏  举报