HDU 2871 Memory Control (line segment tree)

HDU 2871 Memory Control

analysis:

I struggled with this question for many days, and spent another afternoon looking for bugs, changing my mind, and finally finished it. An extremely toxic question is equivalent to one question of three types of line segment trees, four operations:

① Find the smallest x-length interval and cover;

②Delete the interval where a point x is located;

③Find the starting position of the x-th interval;

④Clear all intervals;

Analysis found:

For ④ is to operate multiple times ②

For ②: Need to record each interval of ① and operate in reverse ①

Regarding ①: Since there is no overlap between the intervals, there is no need to store downward updates in the lazy array, or even upward updates. Knowing this can simplify the code. In addition, the storage of the blank interval was originally thought to be the starting point of the maximum interval (later found to be stupid and not feasible), and changed to the classic left and right maximum interval, which is still convenient for querying.

Regarding ③: In fact, it is to find the biggest problem (it seems that there is a blog saying that you can use the binary function in the STL to find it, but it is not clear). Anyway, I added parameters to the original line segment tree to record the target number in the interval How much, basic point operation.

Finally, the complicated operation of voicing this question is really patience. There are hundreds of lines of code to find bugs if there is a little mistake, and there are multiple sets of input and output, and the carriage return between each group is also a service. Personal advice if it is not particularly idle Try not to do this question at the time, it can really crash o(≧口≦)o

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200050;
const int inf = 0x7fffffff;

struct Node
{
	int l;
	int r;
};

int n, m;
int mmax[maxn], lmax[maxn], rmax[maxn], belong[maxn], have[maxn];
int x, ql, qr, qv, presum;
vector<Node>neww;
set<int>reset;

void init()
{
	neww.clear();
	reset.clear();
}

void build(int o, int l, int r)
{
	lmax[o] = rmax[o] = mmax[o] = r - l + 1;
	belong[o] = have[o] = 0;
	if (l == r)return;
	int mid = (l + r) >> 1;
	build(o << 1, l, mid);
	build(o << 1 | 1, mid + 1, r);
}

void update(int o, int l, int r)
{
	if (ql <= l&&r <= qr)
	{
		belong[o] = qv;
		if (qv == 0)lmax[o] = rmax[o] = mmax[o] = r - l + 1;
		else lmax[o] = rmax[o] = mmax[o] = 0;
		return;
	}
	int mid = (l + r) >> 1, lo = o << 1, ro = o << 1 | 1;
	if (ql <= mid)update(lo, l, mid);
	if (qr>mid) update(ro, mid + 1, r);

	lmax[o] = lmax[lo];
	if (lmax[lo] == mid - l + 1)lmax[o] += lmax[ro];
	rmax[o] = rmax[ro];
	if (rmax[ro] == r - mid)rmax[o] += rmax[lo];
	mmax[o] = max(rmax[lo] + lmax[ro], max(mmax[lo], mmax[ro]));
}

void add(int o, int l, int r)
{
	if (l == r)
	{
		have[o] = qv ? 1 : 0;
		return;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid)add(o << 1, l, mid);
	else add(o << 1 | 1, mid + 1, r);
	have[o] = have[o << 1] + have[o << 1 | 1];
}

int query_new(int o, int l, int r)
{
	if (l == r)return l;
	int mid = (l + r) >> 1, lo = o << 1, ro = o << 1 | 1;
	if (mmax[lo] >= x)return query_new(lo, l, mid);
	if (rmax[lo] + lmax[ro] >= x)return mid - rmax[lo] + 1;
	return query_new(ro, mid + 1, r);
}

int query_free(int o, int l, int r)
{
	if (belong[o])return belong[o];
	if (l == r)return 0;
	int mid = (l + r) >> 1;
	if (x <= mid)return query_free(o << 1, l, mid);
	return query_free(o << 1 | 1, mid + 1, r);
}

int query_get(int o, int l, int r)
{
	if (l == r)return l;
	int mid = (l + r) >> 1, lo = o << 1, ro = o << 1 | 1;
	if (presum + have[lo] >= x)return query_get(lo, l, mid);
	presum += have[lo];
	return query_get(ro, mid + 1, r);
}

void delet()
{
	qv = 0;
	update(1, 1, n);
	add(1, 1, n);
}

int main()
{
	while (~scanf("%d%d", &n, &m))
	{
		build(1, 1, n);
		init();
		while (m--)
		{
			char op[10];
			scanf(" %s", op);
			if (op[0] == 'N')
			{
				scanf("%d", &x);
				if (mmax[1]<x)printf("Reject New\n");
				else
				{
					ql = query_new(1, 1, n);
					qr = ql + x - 1;
					neww.push_back((Node){ ql, qr });
					qv = neww.size();
					update(1, 1, n);
					add(1, 1, n);
					printf("New at %d\n", ql);
				}
			}
			else if (op[0] == 'F')
			{
				scanf("%d", &x);
				qv = query_free(1, 1, n);
				if (qv == 0)printf("Reject Free\n");
				else
				{
					reset.insert(qv);

					ql = neww[qv - 1].l;
					qr = neww[qv - 1].r;
					delet();
					printf("Free from %d to %d\n", ql, qr);
				}
			}
			else if (op[0] == 'G')
			{
				scanf("%d", &x);
				if (have[1]<x)printf("Reject Get\n");
				else
				{
					presum = 0;
					printf("Get at %d\n", query_get(1, 1, n));
				}
			}
			else if (op[0] == 'R')
			{
				for (int len = neww.size(), i = 0; i<len; i++)
				{
					if (reset.find(i + 1) == reset.end())
					{
						ql = neww[i].l;
						qr = neww[i].r;
						delet();
					}
				}
				printf("Reset Now\n");
				init();
			}
		}
		printf("\n");
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_43700916/article/details/90905411