Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:Did you initialize array answer[...]?

Posted by insany at 2006-03-15 09:36:41 on Problem 2761
In Reply To:Did you initialize array answer[...]? Posted by:C6H6 at 2006-03-14 22:47:54
I think init of answer array is not needed because it overlaped by another set of questions.

and...

this is my RB Tree. 
but this is very long... that's reason why i didn't post it



#include <cstdio>
#include <cstdlib>
#include <queue>

#include <string>
#include <ctime>
#include <algorithm>
#include <set>

using namespace std;

class Node {
	public:
		Node* left;
		Node* right;
		int red;	// 0 black 1 red
		int key;
		int treesize;
		Node() {
			left = NULL, right = NULL;
			red = 0;
			key = 0;
			treesize = 1;
		}
		Node(int key) {
			left = NULL, right = NULL;
			red = 0;
			this->key = key;
			treesize = 1;
		}
};

class RedBlack {
	public:	
		int treesize;
		Node* base;

		RedBlack() {
			base = new Node();
			treesize = 0;
		}

		~RedBlack() {
			queue<Node*> bfs;
			bfs.push(base);

			while(!bfs.empty()) {
				Node* now = bfs.front();
				bfs.pop();
				if (now) {
					bfs.push(now->left);
					bfs.push(now->right);
					delete now;
					now = NULL;
				}
			}

		}

		int size() {
			return treesize;
		}

		//찾으면 Node* 리턴. 못찾으면 Null 리턴
		//base의 left가 root
		Node* find(int key)
		{
			Node* s = base->left;
			while(s != NULL && s->key != key) {
				if (s->key > key) {
					s = s->left;
				}
				else {
					s = s->right;
				}
			}
			return s;
		}

		int rank(int k)
		{
			if (k < 0 || k > base->left->treesize) return -1;
			Node* s = base->left;
			int nodenum = 1;
			while(1)
			{
				if (s->left) nodenum += s->left->treesize;

				if (nodenum == k) return s->key;
				if (k < nodenum) {
					nodenum -= s->left->treesize;
					s = s->left;
				}
				else {
					nodenum++;
					s = s->right;
				}
			}
			//should not reached
			printf("should not reached!!!!\n");
			(*(int *)0) = 0;
			return -1;
		}

		//pivot의 위치는 변하지 않고, gchild가 회전된 서브트리의 root가 된다.
		//회전된 서브트리의 root의 Pointer가 리턴
		Node* rotate(Node* pivot, int key)
		{
			Node* child, *gchild;
			if (key < pivot->key || pivot == base) child = pivot -> left;
			else child = pivot -> right;

			int save = child->treesize;
			if (key < child->key) {	//L 회전
				gchild = child->left;
				child->treesize -= gchild->treesize;
				if (gchild->right) child->treesize += gchild->right->treesize;

				child->left = gchild->right;
				gchild->right = child;
			}
			else {					//R 회전
				gchild = child->right;
				child->treesize -= gchild->treesize;
				if (gchild->left) child->treesize += gchild->left->treesize;

				child->right = gchild->left;
				gchild->left = child;
			}
			gchild->treesize = save;


			if (key < pivot->key || pivot == base) pivot->left = gchild;
			else pivot->right = gchild;

			return gchild;
		}

		Node* insert(int key)
		{
			Node* t, *parent, *gparent, *ggparent;
			ggparent = gparent = parent = base;
			t = base->left;

			while(t != NULL) {
				if (key == t->key) return NULL;	//이미 같은 키가 존재
				if (t->left != NULL && t-> right != NULL && t->left->red && t->right->red) { //색상변환
					t->red = 1;
					t->left->red = 0, t->right->red = 0;
					if (parent->red) {	//부모가 빨강이면 회전 필요
						gparent->red = 1;
						if ((key < gparent->key) != (key < parent->key)) //LR이나 RL의 첫 회전
							parent = rotate(gparent, key);
						t = rotate(ggparent, key);
						t->red = 0;
					}
					base->left->red = 0;	//root는 항상 검정
				}
				ggparent = gparent;
				gparent = parent;
				parent = t;
				if (key < t->key) t = t->left;
				else t = t->right;
			}

			t = new Node(key);	
			if (key < parent->key || parent == base) parent->left = t;
			else parent->right = t;

			t->red = 1;	//새로 삽입된 노드는 빨강

			//root에서 t의 parent까지 treesize에 1을 더한다
			Node* s = base->left;
			while(s != NULL && s->key != key) {
				s->treesize ++;
				if (s->key > key) {
					s = s->left;
				}
				else {
					s = s->right;
				}
			}

			if (parent->red) {
				gparent->red = 1;
				if ((key < gparent->key) != (key < parent->key)) //LR이나 RL의 첫 회전
					parent = rotate(gparent, key);
				t = rotate(ggparent, key);
				t->red = 0;
			}
			base->left->red = 0;
			

			treesize++;
			return t;
		}


		//삭제 노드와 가장 가까운 빨강 씨앗을 찾아서 빨강 씨앗의 부모의 포인터 리턴
		//이 빨강 씨앗을 아래로 보내면서 삭제한다
		Node* find_seed(int key)
		{
			Node* del, *seed_parent, *parent;
			seed_parent = NULL;
			parent = base;
			del = base->left;

			while(del != NULL) {
				if (key < del->key) {
					//빨강노드나 오른쪽 자식이 빨간 노드 찾기
					if (del->red || (del->right && del->right->red)) seed_parent = parent;
					parent = del;
					del = del->left;
				}
				else {
					//빨강노드나 왼쪽 자식이 빨간 노드 찾기
					if (del->red || (del->left && del->left->red)) seed_parent = parent;
					parent = del;
					del = del->right;
				}
			}
			return seed_parent;
		}


		//원하는 key값의 노드를 red 노드로 만든다.
		//red노드의 leaf노드만 삭제 가능 : 3노드나 4노드이기 때문
		void make_leaf_red(int key)
		{
			Node* seed_parent, *seed, *seed_child;
			seed_parent = find_seed(key);

			if (seed_parent == NULL) {	//빨강 씨앗이 없으면
				seed_parent = base;
				seed = seed_parent->left;
				seed->red = 1;	//루트를 빨강으로 잠시 칠한다
			}
			else {
				//시드 설정
				if (key < seed_parent->key || seed_parent == base) seed = seed_parent->left;
				else seed = seed_parent->right;
			}

			//씨앗이 빨강이 아니면 그 자식을 끌어 올린다.
			if (!seed->red) {
				if (key < seed->key) seed_child = seed->right;
				else seed_child = seed->left;
				seed->red = 1;
				seed_child->red = 0;
				seed_parent = rotate(seed_parent, seed_child->key);
			}

			//외부노드가 아닐 동안
			while(seed->left && seed->right) {
				/*
				   printf("now seed's key value is [%c]\n", seed->key);
				   printf("now seed's left child's key value is [%c]\n", seed->left->key);
				   printf("now seed's right child's key value is [%c]\n", seed->right->key);
				   print(base, 0);
				   */
				seed->red = 0;
				seed->right->red = seed->left->red = 1;

				if (key < seed->key) {
					//if ((seed->right->left || seed->right->right) && 
					//		(seed->right->left->red || seed->right->right->red)) {
					if ((seed->right->left && seed->right->left->red) ||
							(seed->right->right && seed->right->right->red)) {
						if (seed->right->left && seed->right->left->red) {	//RL회전
							seed->right->red = 0;
							rotate(seed, seed->right->left->key);
						}
						else {												//RR회전
							seed->right->right->red = 0;
						}
						rotate(seed_parent, seed->right->key);
					}
					seed_parent = seed;
					seed = seed->left;
				}
				else {
					//if ((seed->left->left || seed->left->right) &&
					//		(seed->left->left->red || seed->left->right->red)) {
					if ((seed->left->left && seed->left->left->red) ||
							(seed->left->right && seed->left->right->red)) {
						if (seed->left->right && seed->left->right->red) {	//LR회전
							seed->left->red = 0;
							rotate(seed, seed->left->right->key);
						}
						else {
							seed->left->left->red = 0;						//LL회전
						}
						rotate(seed_parent, seed->left->key);
					}
					seed_parent = seed;
					seed = seed->right;
				}
			}
		}


		//이 함수를 사용할 떄 반드시 원소가 레드블랙 트리 안에 있는지 체크해 보고 사용할 것!
		//없으면 서브트리의 크기가 뻑남
		//검색하고 시작하도록 해도 되지만 그냥 안했음
		//삭제가 실패하면 NULL 리턴
		Node* erase(int key)
		{
			Node* parent, *del, *center, *pcenter, *son;
			parent = base;
			del = base->left;
			//원소 찾기 : parent를 알아야 하기 때문에 search함수 안씀
			while(del != NULL && key != del->key) {
				del->treesize --;
				parent = del;
				if (key < del->key) del = del->left;
				else del = del->right;
			}
			if (del == NULL) return NULL;
			del->treesize --;

			if (del->right && del->left) {	//내부 노드이면
				pcenter = del;	//삭제할 노드를 대체할 노드를 찾음
				center = del->right;
				while(center->left != NULL) {
					center->treesize--;
					pcenter = center;
					center = center->left; //center는 대체할 키임
				}
				del->key = center->key;	//삭제할 키를 대체할 키로 바꿈
				del = center;			//이제 center를 삭제하도록 조정
				parent = pcenter;
				key = del->key;
			}

			if (del->left || del->right) {	//자식이 하나면 반드시 빨강
				if (del->left) son = del->left;
				else son = del->right;
				son->red = 0;
			}
			else if (del->left == NULL && del->right == NULL) {
				//자식이 없으면 빨강이면 삭제 검정이면 변환 후 삭제
				if (!del->red) make_leaf_red(del->key);
				son = NULL;
			}
			base->left->red = 0;
			if (key < parent->key || parent == base) parent->left = son;
			else parent->right = son;
			delete del;

			treesize--;
			
			return parent;
		}

		void printrecur(Node* node, int depth)
		{
			if (node == NULL) return;
			//for (int i = 0; i < depth; i++) printf("\t");

			printf("%d ", node->key);
			/*
			if (node->red) printf("%c[R](size = %d)\n", (char)(node->key), node->treesize);
			else printf("%c[B](size = %d)\n", (char)(node->key), node->treesize);
			*/

			printrecur(node->left, depth + 1);
			printrecur(node->right, depth + 1);
		}

		void print()
		{
			printf("[");
			printrecur(base->left, 0);
			printf("]\n");
		}
};

int n, m;
int a[100000];
struct query {
	int num;
	int l, r, rank;
};
bool operator < (const query& a, const query& b)
{
	if (a.l == b.l) {
		return (a.r < b.r);
	}
	return (a.l < b.l);
}
query q[50000];
int answer[50000];

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}

	for (int i = 0; i < m; i++) {
		scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].rank);
		if (q[i].l > q[i].r) {
			int temp = q[i].l; q[i].l = q[i].r; q[i].r = temp;
		}
		q[i].l--, q[i].r--;
		q[i].num = i;
		//printf("%d %d %d\n", q[i].l, q[i].r, q[i].rank);
	}
	sort(q, q + m);

	RedBlack rb;

	for (int i = q[0].l; i <= q[0].r; i++) {
		rb.insert(a[i]);
	}
	answer[q[0].num] = rb.rank(q[0].rank);

	for (int i = 1; i < m; i++) {
		if (q[i - 1].r >= q[i].r) {
			(* (int *)0) = 0;
		}
		if (q[i - 1].r < q[i].l) {
			for (int j = q[i - 1].l; j <= q[i - 1].r; j++) rb.erase(a[j]);
			for (int j = q[i].l; j <= q[i].r; j++) rb.insert(a[j]);
		}
		else {
			for (int j = q[i - 1].l; j < q[i].l; j++) rb.erase(a[j]);
			for (int j = q[i - 1].r + 1; j <= q[i].r; j++) rb.insert(a[j]);
		}
		answer[q[i].num] = rb.rank(q[i].rank);
	}

	for (int i = 0; i < m; i++) {
		printf("%d\n", answer[i]);
	}

	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator