首页 > 代码库 > 树状数组之求逆对数
树状数组之求逆对数
Ultra-QuickSort
Ultra-QuickSort produces the output
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
Output
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
3
3 2 1
1
3
2 3 1
0
4
10 8 3 1
4
4
1 5 4 3
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 }
树状数组之求逆对数