Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
- struct AVLNode
- {
- AVLNode * up;
- AVLNode * left;
- AVLNode * right;
- int key;
- long long data;
- int bf;
- int nulls;
- };
- // Rotacja RR
- //-----------
- void RR(AVLNode * & root, AVLNode * A)
- {
- AVLNode * B = A->right, * p = A->up;
- A->nulls -= B->nulls;
- if(B->left) A->nulls += B->left->nulls;
- else A->nulls++;
- if(A->left) B->nulls += A->left->nulls;
- else B->nulls++;
- A->right = B->left;
- if(A->right) A->right->up = A;
- B->left = A;
- B->up = p;
- A->up = B;
- if(p)
- {
- if(p->left == A) p->left = B;
- else p->right = B;
- }
- else root = B;
- if(B->bf == -1) A->bf = B->bf = 0;
- else
- {
- A->bf = -1;
- B->bf = 1;
- }
- }
- // Rotacja LL
- //-----------
- void LL(AVLNode * & root, AVLNode * A)
- {
- AVLNode * B = A->left, * p = A->up;
- A->nulls -= B->nulls;
- if(B->right) A->nulls += B->right->nulls;
- else A->nulls++;
- if(A->right)B->nulls += A->right->nulls;
- else B->nulls++;
- A->left = B->right;
- if(A->left) A->left->up = A;
- B->right = A;
- B->up = p;
- A->up = B;
- if(p)
- {
- if(p->left == A) p->left = B;
- else p->right = B;
- }
- else root = B;
- if(B->bf == 1) A->bf = B->bf = 0;
- else
- {
- A->bf = 1;
- B->bf = -1;
- }
- }
- // Rotacja RL
- //-----------
- void RL(AVLNode * & root, AVLNode * A)
- {
- AVLNode * B = A->right, * C = B->left, * p = A->up;
- B->nulls -= C->nulls;
- if(C->right) B->nulls += C->right->nulls;
- else B->nulls++;
- if(B->right)C->nulls += B->right->nulls;
- else C->nulls++;
- A->nulls -= C->nulls;
- if(C->left) A->nulls += C->left->nulls;
- else A->nulls++;
- if(A->left) C->nulls += A->left->nulls;
- else C->nulls++;
- B->left = C->right;
- if(B->left) B->left->up = B;
- A->right = C->left;
- if(A->right) A->right->up = A;
- C->left = A;
- C->right = B;
- A->up = B->up = C;
- C->up = p;
- if(p)
- {
- if(p->left == A) p->left = C;
- else p->right = C;
- }
- else root = C;
- if(C->bf == -1) A->bf = 1;
- else A->bf = 0;
- if(C->bf == 1) B->bf = -1;
- else B->bf = 0;
- C->bf = 0;
- }
- // Rotacja LR
- //-----------
- void LR(AVLNode * & root, AVLNode * A)
- {
- AVLNode * B = A->left, * C = B->right, * p = A->up;
- B->nulls -= C->nulls;
- if(C->left) B->nulls += C->left->nulls;
- else B->nulls++;
- if(B->left) C->nulls += B->left->nulls;
- else C->nulls++;
- A->nulls -= C->nulls;
- if(C->right) A->nulls += C->right->nulls;
- else A->nulls++;
- if(A->right)C->nulls += A->right->nulls;
- else C->nulls++;
- B->right = C->left;
- if(B->right) B->right->up = B;
- A->left = C->right;
- if(A->left) A->left->up = A;
- C->right = A;
- C->left = B;
- A->up = B->up = C;
- C->up = p;
- if(p)
- {
- if(p->left == A) p->left = C;
- else p->right = C;
- }
- else root = C;
- if(C->bf == 1) A->bf = -1;
- else A->bf = 0;
- if(C->bf == -1) B->bf = 1;
- else B->bf = 0;
- C->bf = 0;
- }
- void insertAVL(AVLNode * & root, int k, long long d)
- {
- AVLNode * w,* p,* r;
- bool t;
- w = new AVLNode; // tworzymy dynamicznie nowy węzeł
- w->left = w->right = w->up = NULL;
- w->key = k;
- w->bf = 0;
- w->data = d;
- w->nulls = 2;
- //----------------------------------------
- // FAZA 1 - wstawienie węzła do drzewa AVL
- //----------------------------------------
- p = root; // rozpoczynamy od korzenia
- if(!p)
- {
- root = w;
- } // jeśli drzewo jest puste, to węzeł w umieszczamy w korzeniu
- else
- {
- // inaczej szukamy miejsce dla w
- while(true)
- {
- p->nulls++;
- if(k < p->key) // porównujemy klucze
- {
- if(!p->left) // jeśli p nie posiada lewego syna, to
- {
- p->left = w; // lewym synem p staje się węzeł w
- break; // wychodzimy z pętli
- }
- p = p->left; // inaczej przechodzimy do lewego syna
- }
- else
- {
- if(!p->right) // jeśli p nie posiada prawego syna, to
- {
- p->right = w; // prawym synem staje się węzeł w
- break; // wychodzimy z pętli
- }
- p = p->right; // inaczej przechodzimy do prawego syna
- }
- }
- w->up = p; // ojcem w jest p
- //---------------------------------
- // FAZA 2 - równoważenie drzewa AVL
- //---------------------------------
- if(p->bf)
- {
- p->bf = 0; // UWAGA NR 1
- }
- else
- {
- if(p->left == w) // UWAGA NR 2
- p->bf = 1;
- else
- p->bf = -1;
- r = p->up; // będziemy szli w górę drzewa w kierunku korzenia
- // r i p wskazują ojca i syna na tej ścieżce
- t = false;
- while(r)
- {
- if(r->bf)
- {
- t = true; // ustalamy wynik pętli
- break; // przerywamy pętlę
- };
- // inaczej modyfikujemy r.bf
- if(r->left == p) r->bf = 1;
- else r->bf = -1;
- p = r; // przechodzimy w górę na wyższy poziom
- r = r->up;
- }
- if(t) // jeśli r.bf = +/- 1, to musimy
- {
- // równoważyć drzewo
- if(r->bf == 1)
- {
- if(r->right == p) r->bf = 0; // gałęzie się równoważą
- else if(p->bf == -1) LR(root,r);
- else LL(root,r);
- }
- else
- {
- // r.bf = -1
- if(r->left == p) r->bf = 0; // gałęzie się równoważą
- else if(p->bf == 1) RL(root,r);
- else RR(root,r);
- }
- }
- }
- }
- }
- AVLNode * findAVL(AVLNode * p, int nr)
- {
- nr++;
- while(p)
- {
- if(nr < 0 || nr > p->nulls) return NULL;
- else if(!p->left)
- {
- if(nr == 1) return p;
- else if(nr > 1)
- {
- nr--;
- p = p->right;
- }
- }
- else if(nr < p->left->nulls) p = p->left;
- else if(nr == p->left->nulls) return p;
- else if(nr > p->left->nulls)
- {
- nr -= p->left->nulls;
- p = p->right;
- }
- }
- return NULL;
- }
- void DFSRelease(AVLNode * v)
- {
- if(v)
- {
- DFSRelease(v->left); // usuwamy lewe poddrzewo
- DFSRelease(v->right); // usuwamy prawe poddrzewo
- delete v; // usuwamy sam węzeł
- }
- }
- AVLNode * predAVL(AVLNode * p)
- {
- AVLNode * r;
- if(p)
- {
- if(p->left)
- {
- p = p->left;
- while(p->right) p = p->right;
- }
- else
- do
- {
- r = p;
- p = p->up;
- }
- while(p && p->right != r);
- }
- return p;
- }
- AVLNode * removeAVL(AVLNode * & root, AVLNode * x)
- {
- AVLNode *t,*y,*z, *tmp;
- bool nest;
- if(x->left && x->right)
- {
- y = removeAVL(root,predAVL(x));
- y->nulls = x->nulls;
- nest = false;
- }
- else
- {
- if(x->left)
- {
- y = x->left;
- x->left = NULL;
- }
- else
- {
- y = x->right;
- x->right = NULL;
- }
- x->bf = 0;
- nest = true;
- }
- if(y)
- {
- y->up = x->up;
- y->left = x->left;
- if(y->left) y->left->up = y;
- y->right = x->right;
- if(y->right) y->right->up = y;
- y->bf = x->bf;
- }
- if(x->up)
- {
- if(x->up->left == x) x->up->left = y;
- else x->up->right = y;
- }
- else root = y;
- if(nest)
- {
- z = y;
- y = x->up;
- tmp = y;
- while(tmp)
- {
- tmp->nulls--;
- tmp = tmp->up;
- }
- while(y)
- {
- if(!y->bf)
- {
- // Przypadek nr 1
- if(y->left == z) y->bf = -1;
- else y->bf = 1;
- break;
- }
- else
- {
- if(((y->bf == 1) && (y->left == z)) || ((y->bf == -1) && (y->right == z)))
- {
- // Przypadek nr 2
- y->bf = 0;
- z = y;
- y = y->up;
- }
- else
- {
- if(y->left == z) t = y->right;
- else t = y->left;
- if(!t->bf)
- {
- // Przypadek 3A
- if(y->bf == 1) LL(root,y);
- else RR(root,y);
- break;
- }
- else if(y->bf == t->bf)
- {
- // Przypadek 3B
- if(y->bf == 1) LL(root,y);
- else RR(root,y);
- z = t;
- y = t->up;
- }
- else
- {
- // Przypadek 3C
- if(y->bf == 1) LR(root,y);
- else RL(root,y);
- z = y->up;
- y = z->up;
- }
- }
- }
- }
- }
- return x;
- }
- inline int readLong(long long *n)
- {
- register int c = getc_unlocked(stdin);
- if(c != EOF)
- {
- (*n) = 0LL;
- while (c > 47)
- {
- (*n)=(*n)*10LL + (c-'0');
- c = getc_unlocked(stdin);
- }
- }
- return c;
- }
- inline int readInt(int *n)
- {
- register int c = getc_unlocked(stdin);
- if(c != EOF)
- {
- (*n) = 0;
- while (c > 47)
- {
- (*n)=(*n)*10 + (c-'0');
- c = getc_unlocked(stdin);
- }
- }
- return c;
- }
- int main()
- {
- AVLNode *POS, *root = NULL, *help;
- register int size = 0, i, t;
- long long current, posData, nr = 0LL;
- readInt(&t);
- for(i = 0 ; readLong(¤t) != EOF; i++)
- {
- insertAVL(root, i, current);
- size++;
- }
- if(size == 0)
- {
- printf("-1");
- return 0;
- }
- POS = findAVL(root, 0);
- for(i = t; i > 0; i--)
- {
- //cout << " nr: " << nr << " data: " << POS->data << endl;
- if(POS->data % 2 == 0)
- {
- //cout << "usuwam: "<<endl;
- help = findAVL(root, (nr + 1) % size);
- posData = help->data;
- removeAVL(root, help);
- size--;
- if(nr == size) nr--;
- if(size == 0)
- {
- printf("-1");
- return 0;
- }
- }
- else
- {
- // cout << "dodaje: " << nr+1 << endl;
- posData = POS->data;
- insertAVL(root, nr, POS->data - 1);
- size++;
- }
- //cout << nr << " + " << posData << " % " << size << " = " << (nr + posData)%size << endl;
- nr = (nr + posData)%size;
- POS = findAVL(root, nr);
- //printBT("", "", root);
- }
- for(i = 0, t = nr; i < size; i++, t = ((t + 1)%size))
- {
- printf("%lld ", findAVL(root, t)->data);
- }
- //DFSRelease(root);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement