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 triplets i, 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.
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.
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).
3 3 2 1
1
3 2 3 1
0
4 10 8 3 1
4
4 1 5 4 3
1
#include <iostream> #include <stdio.h> #include <algorithm> #include <cstring> #define MAX 1000100 using namespace std; struct node { long long val; int pos; }a[MAX]; long long ans[MAX],ans2[MAX]; long long c[MAX]; bool cmp1(node a,node b) { return a.val<b.val; } bool cmp2(node a,node b) { return a.pos<b.pos; } long long lowbit(int x) { return x&(-x); } void add(int po,long long val) { while (po<=MAX) { c[po]+=val; po+=lowbit(po); } } long long getsum(int po) { long long sum=0; while (po>0) { sum+=c[po]; po-=lowbit(po); } return sum; } int main() { int n; freopen("in.txt","r",stdin); while (cin>>n) { if (n==0) break; int i; for (i=1;i<=n;i++) { scanf("%lld",&a[i].val); a[i].pos=i; } sort(a+1,a+n+1,cmp1); //离散化 for (i=1;i<=n;i++) a[i].val=i; sort(a+1,a+n+1,cmp2); memset(c,0,sizeof(c)); //求二元的 memset(ans,0,sizeof(ans)); for (i=1;i<=n;i++) { add(a[i].val,1); ans[i]=i-getsum(a[i].val); } memset(c,0,sizeof(c)); //求三元的 memset(ans2,0,sizeof(ans2)); long long sum=0; for (i=1;i<=n;i++) { add(a[i].val,ans[i]); sum+=ans[i]; //用所有项的总和减去比a[i]小的总和,即的比a[i]大的总和 ans2[i]=sum-getsum(a[i].val); } long long fians=0; for (i=1;i<=n;i++) fians+=ans2[i]; cout<<fians<<endl; } return 0; } /* The first line of input contains a single number n (3 ≤ n ≤ 106) Next line contains n different positive integers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 109) 求三元逆序对 树状数组: 设ans(i)为1到i-1中比a[i]大的元素个数,则显然逆序对数为(∑ans(i),i∈[2,n]). 我们不妨再设一个ans2(i)=∑ans(j)(j∈[2,i-1],A[j]>A[i]),这样,ans2(i)就成为以i结尾的三元逆序组的个数, 则最终答案就是(∑ans2(i),i∈[3,n]). 同理,我们可以迭代计算cardbigger3,cardbigger4,cardbigger5,...,从而计算出K元逆序组. 注意,所有的操作是串联的,也就是说计算K元逆序组只需要把以上算法重复K-1次,所以计算复杂度为O(knlogn), 在k很小的时候则可看作是O(nlogn),算是很高效了. 本体数据量很大,用long long,离散化 */