Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Daniel Grzegorzewski
- #include <bits/stdc++.h>
- #define MP make_pair
- #define PB push_back
- #define ST first
- #define ND second
- using namespace std;
- typedef pair<int, int> PII;
- typedef vector<int> VI;
- typedef vector<PII> VII;
- typedef long long LL;
- void init_ios()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- }
- const int N = (int)1e6 + 10;
- bool flaga;
- struct AVLnode
- {
- AVLnode *left;
- AVLnode *right;
- AVLnode *parent;
- int key, size, bf;
- void create(int value)
- {
- left = NULL;
- right = NULL;
- parent = NULL;
- key = value;
- size = 1;
- bf = 0;
- }
- };
- struct AVLtree
- {
- AVLnode *root;
- void init()
- {
- root = NULL;
- }
- void LL(AVLnode *A)
- {
- AVLnode *B = A->left;
- AVLnode *p = A->parent;
- A->size = 1;
- if (B->right != NULL)
- A->size += B->right->size;
- if (A->right != NULL)
- A->size += A->right->size;
- B->size = 1+A->size;
- if (B->left != NULL)
- B->size += B->left->size;
- A->left = B->right;
- if (A->left != NULL)
- A->left->parent = A;
- B->right = A;
- B->parent = p;
- A->parent = B;
- if (p == NULL)
- root = B;
- else if (p->left == A)
- p->left = B;
- else
- p->right = B;
- if (B->bf == 1) {
- A->bf = 0;
- B->bf = 0;
- }
- else {
- A->bf = 1;
- B->bf = -1;
- }
- }
- void RR(AVLnode *A)
- {
- AVLnode *B = A->right;
- AVLnode *p = A->parent;
- A->size = 1;
- if (A->left != NULL)
- A->size += A->left->size;
- if (B->left != NULL)
- A->size += B->left->size;
- B->size = 1;
- B->size += A->size;
- if (B->right != NULL)
- B->size += B->right->size;
- A->right = B->left;
- if (A->right != NULL)
- A->right->parent = A;
- B->left = A;
- B->parent = p;
- A->parent = B;
- if (p == NULL)
- root = B;
- else if (p->left == A)
- p->left = B;
- else
- p->right = B;
- if (B->bf == -1) {
- A->bf = 0;
- B->bf = 0;
- }
- else {
- A->bf = -1;
- B->bf = 1;
- }
- }
- void LR(AVLnode *A)
- {
- AVLnode *B = A->left;
- AVLnode *C = B->right;
- AVLnode *p = A->parent;
- A->size = 1;
- if (A->right != NULL)
- A->size += A->right->size;
- if (C->right != NULL)
- A->size += C->right->size;
- B->size = 1;
- if (B->left != NULL)
- B->size += B->left->size;
- if (C->left != NULL)
- B->size += C->left->size;
- C->size = A->size + B->size + 1;
- B->right = C->left;
- if (B->right != NULL)
- B->right->parent = B;
- A->left = C->right;
- if (A->left != NULL)
- A->left->parent = A;
- C->right = A;
- C->left = B;
- A->parent = B->parent = C;
- C->parent = p;
- if (p != NULL) {
- 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 RL(AVLnode *A)
- {
- AVLnode *B = A->right;
- AVLnode *C = B->left;
- AVLnode *p = A->parent;
- A->size = 1;
- if (A->left != NULL)
- A->size += A->left->size;
- if (C->left != NULL)
- A->size += C->left->size;
- B->size = 1;
- if (B->right != NULL)
- B->size += B->right->size;
- if (C->right != NULL)
- B->size += C->right->size;
- C->size = A->size + B->size + 1;
- B->left = C->right;
- if (B->left != NULL)
- B->left->parent = B;
- A->right = C->left;
- if (A->right != NULL)
- A->right->parent = A;
- C->left = A;
- C->right = B;
- A->parent = B->parent = C;
- C->parent = p;
- if (p != NULL) {
- 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 insert(int value)
- {
- AVLnode *w = new AVLnode;
- AVLnode *p;
- AVLnode *r;
- AVLnode *pom;
- bool flag = false;
- w->create(value);
- if (root == NULL) {
- root = w;
- return;
- }
- p = root;
- while (true) {
- if (value <= p->key) {
- if (p->left == NULL) {
- p->left = w;
- break;
- }
- p = p->left;
- }
- else {
- if (p->right == NULL) {
- p->right = w;
- break;
- }
- p = p->right;
- }
- }
- w->parent = p;
- pom = p;
- while (pom != NULL) {
- pom->size++;
- pom = pom->parent;
- }
- if (p->bf != 0) {
- p->bf = 0;
- return;
- }
- if (p->left == w)
- p->bf = 1;
- else
- p->bf = -1;
- r = p->parent;
- while (r) {
- if (r->bf != 0) {
- flag = true;
- break;
- }
- if (r->left == p)
- r->bf = 1;
- else
- r->bf = -1;
- p = r;
- r = r->parent;
- }
- if (!flag)
- return;
- if (r->bf == 1) {
- if (r->right == p)
- r->bf = 0;
- else if (p->bf == -1)
- LR(r);
- else
- LL(r);
- }
- else {
- if (r->left == p)
- r->bf = 0;
- else if (p->bf == 1)
- RL(r);
- else
- RR(r);
- }
- }
- };
- void Union(AVLtree &big, AVLnode *sma) //do drzewa big wrzucam drzewo o korzeniu w sma
- {
- if (sma == NULL)
- return;
- if (sma->left != NULL)
- Union(big, sma->left);
- if (sma->right != NULL)
- Union(big, sma->right);
- big.insert(sma->key);
- delete sma;
- }
- int kta(AVLnode *w, int k) //k'ta co do wielkosci liczba w drzewie
- {
- if (k > w->size)
- return 0;
- if (w->left == NULL && k == 1)
- return w->key;
- else if (w->left == NULL)
- return kta(w->right, k-1);
- if (w->left->size == k-1)
- return w->key;
- if (w->left->size > k-1)
- return kta(w->left, k);
- else
- return kta(w->right, k-1-w->left->size);
- }
- double mediana(AVLnode *w)
- {
- if (w == NULL)
- return 0;
- int n = w->size;
- if (n&1)
- return (double)kta(w, (n+1)/2);
- double res = (double)kta(w, n/2);
- res += (double)kta(w, n/2+1);
- res /= 2;
- return res;
- }
- int n, a[N];
- double res;
- vector<double> out;
- list<AVLtree> l;
- AVLtree tree;
- int main()
- {
- init_ios();
- cout<<fixed<<setprecision(4);
- cin >> n;
- for (int i = 1; i <= n; ++i) {
- cin >> a[i];
- tree.init();
- tree.insert(a[i]);
- l.PB(tree);
- }
- for (auto it = l.begin(); it != l.end();) {
- auto tmp = it;
- ++tmp;
- if (tmp == l.end())
- break;
- if (mediana(it->root) > mediana(tmp->root)) {
- if (flaga)
- return 0;
- if (it->root->size <= tmp->root->size) {
- auto rem = it;
- if (rem != l.begin())
- --rem;
- else
- ++rem;
- Union(*tmp, it->root);
- l.erase(it);
- it = rem;
- }
- else {
- Union(*it, tmp->root);
- l.erase(tmp);
- if (it != l.begin())
- --it;
- }
- }
- else
- ++it;
- }
- int t = 1;
- for (auto it = l.begin(); it != l.end(); ++it) {
- double med = mediana(it->root);
- if (flaga)
- return 0;
- for (int i = 1; i <= it->root->size; ++i) {
- out.PB(med);
- res += abs(med-a[t++]);
- }
- }
- cout<<res<<"\n";
- for (int i = 0; i < out.size(); ++i)
- cout<<out[i]<<"\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement