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

~~-_-|', Long... 13K.(Inside)

Posted by C6H6 at 2006-03-15 14:20:06 on Problem 2761
In Reply To:Re:Did you initialize array answer[...]? Posted by:insany at 2006-03-15 09:36:41
Perhaps you didn't take into account the case that there are some numbers of the same value in the input.
Give you a set of data your code failed to deal with:
7 3
1 5 1 1 1 2 2
1 3 2
2 4 1
3 7 3

Correct ans:
1
1
1

Yours:
5
1
-1
( vc6.0 c++ )

Sorry your code is too long for me to read. What's more, I didn't use
class before. It makes me be afraid of your program.
:)

> 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