| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
~~-_-|', Long... 13K.(Inside)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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator