首页 > 代码库 > 树状数组之求逆对数

树状数组之求逆对数

 Ultra-QuickSort

 
 
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
9 1 0 5 4 ,

Ultra-QuickSort produces the output 
0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

题目是求每个数前面比它大的数量的总和,就是逆对数了。只要是离散化就可以做了。i-query(index[i]):当前是对i个数,query(index[i])是它前面比它小的数,减去它就是前面比它大的数量了。
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define lowbit(x) x&(-x)
 6 #define ll long long
 7 using namespace std;
 8 const int MAX = 5e5+5;
 9 int n, tree[MAX],index[MAX];
10 struct Nod{
11     int num,id;
12 }nod[MAX];
13 bool cmp(Nod a, Nod b){
14     return a.num < b.num;
15 }
16 void add(int x, int y){
17     while(x < MAX){
18         tree[x] += y;
19         x += lowbit(x);
20     }
21 }
22 
23 int query(int x){
24     int sum = 0;
25     while(x > 0){
26         sum += tree[x];
27         x -= lowbit(x);
28     }
29     return sum;
30 }
31 int main(){
32     while(scanf("%d",&n)&&n){
33         for(int i = 1; i <= n; i ++){
34             scanf("%d",&nod[i].num);
35             nod[i].id = i;
36         }
37         sort(nod+1,nod+1+n,cmp);
38         for(int i = 1; i <= n; i ++)index[nod[i].id] = i;
39         memset(tree,0,sizeof(tree));
40         ll ans = 0;
41         for(int i = 1; i <= n; i ++){
42             add(index[i],1);
43             //printf("%d+++++%d\n",index[i],query(index[i]));
44             ans += i-query(index[i]);
45         }
46         printf("%lld\n",ans);
47     }
48 }

 

 

 

Enemy is weak

 

 

The Romans have attacked again. This time they are much more than the Persians but Shapur is ready to defeat them. He says: "A lion is never afraid of a hundred sheep".

Nevertheless Shapur has to find weaknesses in the Roman army to defeat them. So he gives the army a weakness number.

In Shapur‘s opinion the weakness of an army is equal to the number of tripletsi,?j,?k such that i?<?j?<?k and ai?>?aj?>?ak where ax is the power of man standing at position x. The Roman army has one special trait — powers of all the people in it are distinct.

Help Shapur find out how weak the Romans are.

Input

The first line of input contains a single number n (3?≤?n?≤?106) — the number of men in Roman army. Next line contains n different positive integers ai (1?≤?i?≤?n,?1?≤?ai?≤?109) — powers of men in the Roman army.

Output

A single integer number, the weakness of the Roman army.

Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).

Example

Input
3
3 2 1
Output
1
Input
3
2 3 1
Output
0
Input
4
10 8 3 1
Output
4
Input
4
1 5 4 3
Output
1


这个就是求三个递增的数量,也可以看成第i个数,求前面比它大的数量和后面比它小的数量。下面k是前面比它大的数量,
求后面比它小的数量:由于k是第i个数前面比第i个数大的数量,所以后面比第i个数小的数量
                 为(n-index[i])-(i-1-k)就是n-i-index[i]+k+1,(n-index[i])是比第i个数小的
                 总数,把它减去前面比第i个数小的数量就是后面的数量了,前面比第i个数小的
                 数量为(i-1-k),所以(n-index[i])-(i-1-k)就推来了
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define lowbit(x) x&(-x)
 6 #define ll long long
 7 using namespace std;
 8 const int MAX = 1e6+10;
 9 int n,tree[MAX],index[MAX];
10 int nex[MAX],pre[MAX];
11 struct Nod{
12     int val,id;
13 }nod[MAX];
14 bool cmp(Nod a, Nod b){
15     return a.val > b.val;
16 }
17 void add(int x){
18     while(x < MAX){
19         tree[x] ++;
20         x += lowbit(x);
21     }
22 }
23 int query(int x){
24     int sum = 0;
25     while(x > 0){
26         sum += tree[x];
27         x -= lowbit(x);
28     }
29     return sum;
30 }
31 int main(){
32     scanf("%d",&n);
33     for(int i = 1; i <= n; i ++)scanf("%d",&nod[i].val),nod[i].id=i;
34     sort(nod+1,nod+1+n,cmp);
35     for(int i = 1; i <= n; i ++)index[nod[i].id] = i;
36     ll ans = 0,k;
37     
38     for(int i = 1; i <= n; i ++){
39         k = query(index[i]);
40         ans += k*(n-i-index[i]+k+1);
41         add(index[i]);
42     }
43     cout << ans << endl;
44     return 0;
45 }

 

树状数组之求逆对数