hdoj 2871 Memory Control

hdoj 2871 

poj 3667 hotel套了个马甲 

线段树基本操作不用变,按分配内存先后分别标记每个内存块的编号,增加一个查找某点所属内存块的编号的函数

记录每个内存块的起始位置和结束位置,然后维护一颗BST,以起始编号为主键,求第k大即可

线段树+SBT

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits> 
#include <set>
#include <string> 
#include <sstream>
#include <utility>
#include <ctime>

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;

const int MAXN(50010);

struct ELE
{
	int key1, key2;
	ELE(int tk1 = 0, int tk2 = 0): key1(tk1), key2(tk2)
	{}

	friend bool operator < (const ELE &op1, const ELE &op2)
	{
		return op1.key1 < op2.key1;
	}
	friend bool operator > (const ELE &op1, const ELE &op2)
	{
		return op1.key1 > op2.key1;
	}
	friend bool operator >= (const ELE &op1, const ELE &op2)
	{
		return op1.key1 >= op2.key1;
	}
	friend bool operator == (const ELE &op1, const ELE &op2)
	{
		return op1.key1 == op2.key1;
	}
	friend ELE operator +(ELE op1, int op2)
	{
		op1.key1 += op2;
		return op1;
	}
};

template<typename T>
struct SBT
{
	struct NODE
	{
		T key;
		int size;
		NODE *left;
		NODE *right;
	};

	NODE pool[MAXN];
	NODE *root, *NIL, *rear;
	T tkey;
	void init()
	{
		NIL = pool;
		rear = pool+1;
		NIL->size = 0;
		NIL->left = NIL;
		NIL->right = NIL;
		root = NIL;
	}

	NODE *newnode(const T &value)
	{
		rear->key = value;
		rear->left = NIL;
		rear->right = NIL;
		rear->size = 1;
		return rear++;
	}
	
	void left_rotate(NODE *&sour)
	{
		NODE *temp = sour->right;
		sour->right = temp->left;
		temp->left = sour;
		temp->size = sour->size;
		sour->size = sour->left->size+sour->right->size+1;
		sour = temp;
	}

	void right_rotate(NODE *&sour)
	{
		NODE *temp = sour->left;
		sour->left = temp->right;
		temp->right = sour;
		temp->size = sour->size;
		sour->size = sour->left->size+sour->right->size+1;
		sour = temp;
	}

	void maintain(NODE *&sour, bool flag)
	{
		if(flag == false)
		{
			if(sour->left->left->size > sour->right->size)
			{
				right_rotate(sour);
			}
			else
				if(sour->left->right->size > sour->right->size)
				{
					left_rotate(sour->left);
					right_rotate(sour);
				}
				else
					return;
		}
		else
		{
			if(sour->right->right->size > sour->left->size)
			{
				left_rotate(sour);
			}
			else
				if(sour->right->left->size > sour->left->size)
				{
					right_rotate(sour->right);
					left_rotate(sour);
				}
				else
					return;
		}
		maintain(sour->right, true);
		maintain(sour->left, false);
		maintain(sour, true);
		maintain(sour, false);
	}
	
	void insert(const T &value)
	{
		tkey = value;
		insert_(root);
	}

	void insert_(NODE *&sour)
	{
		if(sour == NIL)
		{
			sour = newnode(tkey);
			return;
		}
		++sour->size;
		if(tkey < sour->key)
			insert_(sour->left);
		else
			insert_(sour->right);
		maintain(sour, tkey >= sour->key);
	}

	void erase(T value)
	{
		erase_(root, value);
	}

	T erase_(NODE *&sour, const T &value)
	{
		--sour->size;
		if(value == sour->key || (value < sour->key && sour->left == NIL) || (value > sour->key && sour->right == NIL))
		{
			T temp = sour->key;
			if(sour->left == NIL || sour->right == NIL)
				sour = sour->left-NIL+sour->right;
			else
				sour->key = erase_(sour->left, value+1);
			return temp;
		}

		if(value < sour->key)
			return erase_(sour->left, value);
		else
			return erase_(sour->right, value);
	}

	NODE *select(int r)
	{
		NODE *sour = root;
		while(sour != NIL && r != sour->left->size+1)
		{
			if(r <= sour->left->size)
				sour = sour->left;
			else
			{
				r -= sour->left->size+1;
				sour = sour->right;
			}
		}
		return sour;
	}
};

struct SEGMENT_TREE
{
	int cover[MAXN << 2], lsum[MAXN << 2], rsum[MAXN << 2], msum[MAXN << 2];
	inline int left_son(int root)
	{
		return root << 1;
	}

	inline int right_son(int root)
	{
		return (root << 1)|1;
	}

	void push_up(int root, int l1, int l2)
	{
		lsum[root] = lsum[left_son(root)];
		rsum[root] = rsum[right_son(root)];
		if(lsum[root] == l1)
			lsum[root] += lsum[right_son(root)];
		if(rsum[root] == l2)
			rsum[root] += rsum[left_son(root)];
		msum[root] = max(rsum[left_son(root)]+lsum[right_son(root)], max(msum[left_son(root)], msum[right_son(root)]));
	}

	void push_down(int root, int l1, int l2)
	{
		if(cover[root] != -1)
		{
			cover[left_son(root)] = cover[right_son(root)] = cover[root];
			lsum[left_son(root)] = rsum[left_son(root)] = msum[left_son(root)] = cover[root]? 0: l1;
			lsum[right_son(root)] = rsum[right_son(root)] = msum[right_son(root)] = cover[root]? 0: l2;
			cover[root] = -1;
		}
	}

	void build_tree(int l, int r, int root)
	{
		cover[root] = -1;
		lsum[root] = rsum[root] = msum[root] = r-l+1;
		if(l == r)
			return;
		int m = (l+r) >> 1;
		build_tree(l, m, left_son(root));
		build_tree(m+1, r, right_son(root));
	}
	
	int allocate(int op, int l, int r, int root)
	{
		if(l == r)
			return l;
		int m = (l+r) >> 1;
		push_down(root, m-l+1, r-m);
		if(op <= msum[left_son(root)])
			return allocate(op, l, m, left_son(root));
		else
			if(op <= rsum[left_son(root)]+lsum[right_son(root)])
				return m-rsum[left_son(root)]+1;
			else
				return allocate(op, m+1, r, right_son(root));
	}

	void updata(int op, int ql, int qr, int l, int r, int root)
	{
		if(ql <= l && qr >= r)
		{
			lsum[root] = rsum[root] = msum[root] = op? 0: r-l+1;
			cover[root] = op;
			return;
		}
		int m = (l+r) >> 1;
		push_down(root, m-l+1, r-m);
		if(ql <= m)
			updata(op, ql, qr, l, m, left_son(root));
		if(qr > m)
			updata(op, ql, qr, m+1, r, right_son(root));
		push_up(root, m-l+1, r-m);
	}

	int query(int op, int l, int r, int root)
	{
		if(cover[root] != -1)
			return cover[root];
		if(l == r)
			return 0;
		int m = (l+r) >> 1;
		if(op <= m)
			return query(op, l, m, left_son(root));
		else
			return query(op, m+1, r, right_son(root));
	}
};

SEGMENT_TREE st;

SBT<ELE> sbt;

int s[MAXN], e[MAXN];
int count;

char str[10];

int main()
{
	int n, m, temp;
	int op;
	while(~scanf("%d%d", &n, &m))
	{
		st.build_tree(1, n, 1);
		sbt.init();
		count = 0;
		for(int i = 0; i < m; ++i)
		{
			scanf("%s", str);
			switch(str[0])
			{
			case 'R':	st.updata(0, 1, n, 1, n, 1);
						printf("Reset Now\n");
						sbt.init();
						break;
			case 'N':	scanf("%d", &op);
						if(op > st.msum[1])
						{
							printf("Reject New\n");
						}
						else
						{
							temp = st.allocate(op, 1, n, 1);
							printf("New at %d\n", temp);
							++count;
							s[count] = temp;
							e[count] = temp+op-1;
							st.updata(count, s[count], e[count], 1, n, 1);
							sbt.insert(ELE(s[count], e[count]));
						}
						break;
			case 'F':	scanf("%d", &op);
						temp = st.query(op, 1, n, 1);
						if(temp)
						{
							printf("Free from %d to %d\n", s[temp], e[temp]);
							st.updata(0, s[temp], e[temp], 1, n, 1);
							sbt.erase(ELE(s[temp], e[temp]));
						}
						else
						{
							printf("Reject Free\n");
						}
						break;
			case 'G':	scanf("%d", &op);
						SBT<ELE>::NODE *ret = sbt.select(op);
						if(ret == sbt.NIL)
						{
							printf("Reject Get\n");
						}
						else
						{
							printf("Get at %d\n", ret->key.key1);
						}
						break;
			}
		}
		printf("\n");
	}
	return 0;
}

splay+treap

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits> 
#include <set>
#include <string> 
#include <sstream>
#include <utility>
#include <ctime>

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;

const int MAXN(50010);
const int INFI((INT_MAX-1) >> 1);

int n;

struct SPLAY_TREE 
{
	struct NODE
	{
		int cover;
		int key;
		int lsum, rsum, msum;
		int color;
		int size;
		NODE *fa;
		NODE *ch[2];
	};

	NODE pool[MAXN];
	NODE *root, *NIL, *rear;

	void init()
	{
		rear = pool+1;
		NIL = pool;
		NIL->key = -1;
		NIL->cover = -1;
		NIL->size = NIL->lsum = NIL->rsum = NIL->msum = 0;
		NIL->color = MAXN;
		NIL->ch[0] = NIL->ch[1] = NIL->fa = NIL;
		newnode(root, NIL, 0, MAXN);
		newnode(root->ch[1], root, n+1, MAXN);
		build_tree(root->ch[1]->ch[0], root->ch[1], 1, n);
		push_up(root->ch[1]);
		push_up(root);
	}

	void newnode(NODE *&sour, NODE *f, int tk, int tc)
	{
		rear->key = tk;
		rear->color = tc;
		rear->cover = -1;
		rear->size = 1;
		rear->fa = f;
		rear->ch[0] = rear->ch[1] = NIL;
		sour = rear++;
	}

	void push_up(NODE *sour)
	{
		sour->lsum = sour->ch[0]->lsum;
		sour->rsum = sour->ch[1]->rsum;
		sour->msum = 0;
		if(sour->color == 0)
		{
			if(sour->lsum == sour->ch[0]->size)
				sour->lsum += 1+sour->ch[1]->lsum;
			if(sour->rsum == sour->ch[1]->size)
				sour->rsum += 1+sour->ch[0]->rsum;
			sour->msum = sour->ch[0]->rsum+sour->ch[1]->lsum+1;
		}		
		sour->msum = max(sour->msum, max(sour->ch[0]->msum, sour->ch[1]->msum));
		sour->size = sour->ch[0]->size+sour->ch[1]->size+1;
	}

	void push_down(NODE *sour)
	{
		if(sour->cover != -1)
		{
			sour->ch[0]->cover = sour->ch[0]->color = sour->cover;
			sour->ch[1]->cover = sour->ch[1]->color = sour->cover;
			sour->ch[0]->lsum = sour->ch[0]->rsum = sour->ch[0]->msum = sour->cover? 0: sour->ch[0]->size;
			sour->ch[1]->lsum = sour->ch[1]->rsum = sour->ch[1]->msum = sour->cover? 0: sour->ch[1]->size;
			sour->cover = -1;
		}
	}

	void build_tree(NODE *&sour, NODE *f, int l, int r)
	{
		if(l > r)
			return;
		int m = (l+r) >> 1;
		newnode(sour, f, m, 0);
		build_tree(sour->ch[0], sour, l, m-1);
		build_tree(sour->ch[1], sour, m+1, r);
		push_up(sour);
	}

	void rotate(NODE *&sour, int flag)
	{
		NODE *f = sour->fa;
		push_down(f);
		push_down(sour);
		f->ch[!flag] = sour->ch[flag];
		sour->ch[flag]->fa = f;
		sour->fa = f->fa;
		if(f->fa != NIL)
			f->fa->ch[f->fa->ch[1] == f] = sour;
		sour->ch[flag] = f;
		f->fa = sour;
		push_up(f);
	}

	void splay(NODE *sour, NODE *goal)
	{
		push_down(sour);
		while(sour->fa != goal)
		{
			if(sour->fa->fa == goal)
				rotate(sour, sour->fa->ch[0] == sour);
			else
			{
				NODE *f = sour->fa;
				int flag = (f->fa->ch[0] == f);
				if(f->ch[flag] == sour)
					rotate(sour, !flag);
				else
					rotate(f, flag);
				rotate(sour, flag);
			}
		}
		push_up(sour);
		if(goal == NIL)
			root = sour;
	}

	NODE *select(int r, NODE *sour)
	{
		push_down(sour);
		while(sour != NIL && r != sour->ch[0]->size+1)
		{
			if(r <= sour->ch[0]->size)
				sour = sour->ch[0];
			else
			{
				r -= sour->ch[0]->size+1;
				sour = sour->ch[1];
			}
			push_down(sour);
		}
		return sour;
	}

	NODE *find(int op, NODE *sour)
	{
		if(op > sour->msum)
			return NIL;
		push_down(sour);
		NODE *ret;
		while(sour != NIL)
		{
			if(op <= sour->ch[0]->msum)
				sour = sour->ch[0];
			else
				if(sour->color == 0 && op <= sour->ch[0]->rsum+sour->ch[1]->lsum+1)
				{
					ret = select(sour->ch[0]->size-sour->ch[0]->rsum+1, sour);
					break;
				}
				else
					sour = sour->ch[1];
			push_down(sour);
		}
		return ret;
	}

	NODE *allocate(int op)
	{
		NODE *sour;
		sour = select(1, root);
		splay(sour, NIL);
		sour = select(n+2, root);
		splay(sour, root);
		sour = find(op, root->ch[1]->ch[0]);
		return sour;
	}

	void change(int op, int ql, int qr)
	{
		NODE *sour;
		sour = select(ql, root);
		splay(sour, NIL);
		sour = select(qr+2, root);
		splay(sour, root);
		sour = root->ch[1]->ch[0];
		sour->color = sour->cover = op;
		sour->lsum = sour->rsum = sour->msum = op? 0: sour->size;
		push_up(root->ch[1]);
		push_up(root);
	}

	int query(int op)
	{
		NODE *sour = select(op+1, root);
		splay(sour, NIL);
		return root->color;
	}
};

struct TREAP
{
	struct NODE
	{
		int key;
		int fix;
		int size;
		NODE *left, *right;
	};

	NODE pool[MAXN];
	NODE *root, *NIL, *rear;
	int tkey;

	void init()
	{
		rear = pool+1;
		NIL = pool;
		NIL->left = NIL;
		NIL->right = NIL;
		NIL->size = 0;
		NIL->fix = INFI;
		root = NIL;
	}

	void newnode(NODE *&sour, int value)
	{
		rear->key = value;
		rear->fix = rand();
		rear->size = 1;
		rear->left = rear->right = NIL;
		sour = rear++;
	}

	void left_rotate(NODE *&sour)
	{
		NODE *temp = sour->right;
		sour->right = temp->left;
		temp->left = sour;
		temp->size = sour->size;
		sour->size = sour->left->size+sour->right->size+1;
		sour = temp;
	}

	void right_rotate(NODE *&sour)
	{
		NODE *temp = sour->left;
		sour->left = temp->right;
		temp->right = sour;
		temp->size = sour->size;
		sour->size = sour->left->size+sour->right->size+1;
		sour = temp;
	}

	void insert(int value)
	{
		tkey = value;
		insert_(root);
	}

	void insert_(NODE *&sour)
	{
		if(sour == NIL)
		{
			newnode(sour, tkey);
			return;
		}
		++sour->size;
		if(tkey < sour->key)
		{
			insert_(sour->left);
			if(sour->left->fix < sour->fix)
				right_rotate(sour);
		}
		else
		{
			insert_(sour->right);
			if(sour->right->fix < sour->fix)
				left_rotate(sour);
		}
	}

	void erase(int value)
	{
		erase_(root, value);
	}

	void erase_(NODE *&sour, int value)
	{
		if(value == sour->key)
		{
			if(sour->left == NIL || sour->right == NIL)
				sour = sour->left-NIL+sour->right;
			else
			{
				--sour->size;
				if(sour->left->fix < sour->right->fix)
				{
					right_rotate(sour);
					erase_(sour->right, value);
				}
				else
				{
					left_rotate(sour);
					erase_(sour->left, value);
				}
			}
			return;
		}
		--sour->size;
		if(value < sour->key)
			erase_(sour->left, value);
		else
			erase_(sour->right, value);
	}

	NODE *select(int r)
	{
		NODE *sour = root;
		while(sour != NIL && r != sour->left->size+1)
		{
			if(r <= sour->left->size)
				sour = sour->left;
			else
			{
				r -= sour->left->size+1;
				sour = sour->right;
			}
		}
		return sour;
	}
};

SPLAY_TREE splay;
TREAP treap;

int s[MAXN], e[MAXN];
int count;

char str[10];

int main()
{
	int m, op;
	while(~scanf("%d%d", &n, &m))
	{
		splay.init();
		treap.init();
		count = 0;
		SPLAY_TREE::NODE *p1;
		TREAP::NODE *p2;
		int temp;
		for(int i = 0; i < m; ++i)
		{
			scanf("%s", str);
			switch(str[0])
			{
			case 'R':	splay.change(0, 1, n);
						treap.init();
						count = 0;
						printf("Reset Now\n");
						break;
			case 'N':	scanf("%d", &op);
						p1 = splay.allocate(op);
						if(p1 != splay.NIL)
						{
							++count;
							s[count] = p1->key;
							e[count] = p1->key+op-1;
							treap.insert(p1->key);
							splay.change(count, s[count], e[count]);
							printf("New at %d\n", p1->key);
						}
						else
							printf("Reject New\n");
						break;
			case 'F':	scanf("%d", &op);
						temp = splay.query(op);
						if(temp != 0)
						{
							treap.erase(s[temp]);
							splay.change(0, s[temp], e[temp]);
							printf("Free from %d to %d\n", s[temp], e[temp]);
						}
						else
							printf("Reject Free\n");
						break;
			case 'G':	scanf("%d", &op);
						p2 = treap.select(op);
						if(p2 != treap.NIL)
						{
							printf("Get at %d\n", p2->key);
						}
						else
							printf("Reject Get\n");
						break;
			}
		}
		printf("\n");
	}
	return 0;
}



你可能感兴趣的:(hdoj 2871 Memory Control)