POJ 3481 더 블 큐 (데이터 구조)

4643 단어 데이터 구조
제목 유형  데이터 구조
제목
일련의 지령 을 내리다
지령 1 우선 순위 가 B 값 이 A 인 사람 을 삽입 합 니 다.
지령 2 우선 순위 가 가장 높 은 사람 을 제거 하고 이 사람의 값 을 출력 합 니 다.
지령 우선 순위 가 가장 낮은 사람 을 제거 하고 이 사람의 값 을 출력 합 니 다.
문제 풀이 방법
여러 가지 방법 을 할 수 있 습 니 다. 예 를 들 어 우선 줄 트 리 treap 스 트 레 칭 트 리 등 입 니 다.
참조 코드 - 궁금 한 점 이 있 으 시 면 아래 에 댓 글 을 남 겨 주시 면 바로 답 해 드 리 겠 습 니 다.
treap
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>

using namespace std;

const int maxn = 30000 + 10;
int a[maxn], b[maxn];

struct Node {
	Node * ch[2];
	int r;
	int v;
	int msg;
	Node(int v, int msg) : v(v), msg(msg) { ch[0] = ch[1] = NULL; r = rand(); }
	int cmp(int x) const {
		if(x == v) return -1;
		return x < v ? 0 : 1;
	}
};

struct Treap {
	Node * rt;
	Treap() { rt = NULL; }
	
	void rotate(Node* & o, int d) {
		Node * k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o; o = k;
	}

	void insert(Node* & o, int x, int msg) {
		if(o == NULL) o = new Node(x, msg);
		else {
			int d = (x > o->v ? 1 : 0); //         
			insert(o->ch[d], x, msg);
			if(o->ch[d]->r > o->r) rotate(o, d ^ 1);
		}
	}

	void remove(Node* & o, int x) {
		int d = o->cmp(x);
		if(d == -1) {
			Node * u = o;
			if(o->ch[0] != NULL && o->ch[1] != NULL) {
				int d2 = (o->ch[0] > o->ch[1] ? 1 : 0);
				rotate(o, d2); remove(o->ch[d2], x);
			}
			else {
				if(o->ch[0] == NULL) o = o->ch[1]; else o = o->ch[0];
				delete u;
			}
		}
		else remove(o->ch[d], x);
	}

	void removetree(Node* & x) {
		if(x == NULL) return ;
		if(x->ch[0] != NULL) removetree(x->ch[0]);
		if(x->ch[1] != NULL) removetree(x->ch[1]);
		delete x;
		x = NULL;
	}
};

int main() {
	freopen("in", "r", stdin);
  srand(time(0));

	int n;
	Treap trp;
	while(scanf("%d", &n), n) {
		if(n == 1) {
			int msg, x;
			scanf("%d%d", &msg, &x);
			trp.insert(trp.rt, x, msg);
		}
		else if(n == 2) {
			if(trp.rt == NULL) printf("0
"); else { Node * t = trp.rt; while(t->ch[1] != NULL) t = t->ch[1]; printf("%d
", t->msg); trp.remove(trp.rt, t->v); } } else { if(trp.rt == NULL) printf("0
"); else { Node * t = trp.rt; while(t->ch[0] != NULL) t = t->ch[0]; printf("%d
", t->msg); trp.remove(trp.rt, t->v); } } } trp.removetree(trp.rt); return 0; }

splay
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>

using namespace std;

struct Node {
	Node * ch[2];
	int v;
	int msg;
	Node(int v, int msg) : v(v), msg(msg) { ch[0] = ch[1] = NULL; }
	int cmp(int x) const {
		if(x == v) return -1;
		return x < v ? 0 : 1;
	}
};

struct Splay {
	Node * rt;
	Splay() { rt = NULL; }
	void rotate(Node* & o, int d) {
		Node * k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o; o = k;
	}

	void splay(Node* & o, int x) {
		int d = o->cmp(x);
		if(d != -1) {
			Node * p = o->ch[d];
			int d2 = p->cmp(x);
			if(d2 != -1) {
				splay(p->ch[d2], x);
				if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d);
			}
			rotate(o, d^1);
		}
	}

	void insert(Node* & o, int x, int msg) {
		if(o == NULL) {
			o = new Node(x, msg);
			splay(rt, x);
		}
		else {
			int d = (x < o->v ? 0 : 1); // avoid repetition
			insert(o->ch[d], x, msg);
		}
	}

	int findMax(Node* & o) {
		Node * t = o;
		while(t->ch[1] != NULL) {
			t = t->ch[1];
		}
		splay(o, t->v);
		return o->msg;
	}

	int findMin(Node* & o) {
		Node * t = o;
		while(t->ch[0] != NULL) {
			t = t->ch[0];
		}
		splay(o, t->v);
		return o->msg;
	}

	void remove(int x) {
		splay(rt, x);

		Node * t = rt;
		if(rt->ch[0] == NULL) {
			rt = rt->ch[1];
			delete t;
		}
		else {
			findMax(rt->ch[0]);
			rt->ch[0]->ch[1] = rt->ch[1];
			rt = rt->ch[0];
			delete t;
		}
	}
};

int main() {
//	freopen("in", "r", stdin);

	Splay spy;
	int n;
	while(scanf("%d", &n), n) {
		if(n == 1) {
			int x, msg;
			scanf("%d%d", &msg, &x);
			spy.insert(spy.rt, x, msg);
		}
		else if(n == 2) {
			if(spy.rt == NULL) printf("0
"); else { printf("%d
", spy.findMax(spy.rt)); spy.remove(spy.rt->v); } } else { if(spy.rt == NULL) printf("0
"); else { printf("%d
", spy.findMin(spy.rt)); spy.remove(spy.rt->v); } } } return 0; }

좋은 웹페이지 즐겨찾기