Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<cstdio>
- //#include<set>
- #include<vector>
- #include<queue>
- #define MAXN 200000
- inline long long int min(long long int a, long long int b) { return a < b ? a : b; }
- inline int max(int a, int b) { return a < b ? b : a; }
- struct Tree
- {
- bool isLeaf;
- int leftChild;
- int rightChild;
- int value;
- //int deep;
- int numberOfLeafs;
- };
- struct V
- {
- V(int a);
- V(V a, V b);
- std::vector<int> numbers;
- long long int inversions;
- };
- V::V(int a)
- {
- inversions = 0;
- numbers.push_back(a);
- }
- V::V(V a, V b)
- {
- long long int inversionsInTheFirstCase = 0;
- long long int inversionsInTheSecondCase = 0;
- //
- // first case
- {
- std::queue<int> q;
- for(std::vector<int>::iterator i = a.numbers.begin(); i != a.numbers.end(); i++)
- q.push(*i);
- for(std::vector<int>::iterator i = b.numbers.begin(); i != b.numbers.end(); i++)
- {
- while(!q.empty() && q.front() < (*i))
- q.pop();
- inversionsInTheFirstCase += q.size();
- }
- }
- //
- // second case
- {
- std::queue<int> q;
- for(std::vector<int>::iterator i = b.numbers.begin(); i != b.numbers.end(); i++)
- q.push(*i);
- for(std::vector<int>::iterator i = a.numbers.begin(); i != a.numbers.end(); i++)
- {
- while(!q.empty() && q.front() < (*i))
- q.pop();
- inversionsInTheSecondCase += q.size();
- }
- }
- //
- // updating inversions number
- inversions = a.inversions + b.inversions + min(inversionsInTheFirstCase, inversionsInTheSecondCase);
- //
- // merging sets
- {
- int iA = 0;
- int iB = 0;
- while(iA < a.numbers.size() && iB < b.numbers.size())
- {
- if(a.numbers[iA] < b.numbers[iB])
- {
- numbers.push_back(a.numbers[iA]);
- iA++;
- }
- else
- {
- numbers.push_back(b.numbers[iB]);
- iB++;
- }
- }
- while(iA < a.numbers.size())
- {
- numbers.push_back(a.numbers[iA]);
- iA++;
- }
- while(iB < b.numbers.size())
- {
- numbers.push_back(b.numbers[iB]);
- iB++;
- }
- }
- };
- int n, p, treeSize;
- Tree tree[3 * MAXN];
- int GetInput()
- {
- int position = treeSize;
- treeSize++;
- scanf("%d", &p);
- if(p != 0)
- {
- tree[position].isLeaf = true;
- tree[position].value = p;
- tree[position].numberOfLeafs = 1;
- }
- else
- {
- tree[position].isLeaf = false;
- tree[position].leftChild = GetInput();
- tree[position].rightChild = GetInput();
- tree[position].numberOfLeafs = max(tree[tree[position].leftChild].numberOfLeafs, tree[tree[position].rightChild].numberOfLeafs);
- }
- return position;
- }
- V MakeOutput(int position)
- {
- if(tree[position].isLeaf == true)
- return V(tree[position].value);
- else
- {
- if(tree[tree[position].leftChild].numberOfLeafs > tree[tree[position].rightChild].numberOfLeafs)
- return V(MakeOutput(tree[position].leftChild), MakeOutput(tree[position].rightChild));
- else
- return V(MakeOutput(tree[position].rightChild), MakeOutput(tree[position].leftChild));
- }
- }
- int main()
- {
- scanf("%d", &n);
- GetInput();
- printf("%lld", MakeOutput(0).inversions);
- return 0;
- }
Add Comment
Please, Sign In to add comment