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 思路: big[i] 记录是比a[i] 大且位于a[i] 前面的数的个数; little[i] 是记录比a[i] 小 且位于 a[i] 后面数的个数; 那么 big[i]个数中选一个,a[i], little[i]中选一个, 这样的组合肯定满足题目要求; 所以 ans= ans+ big[i]*1*little[i] (for i=0 到 n ) 怎么最快的求big[i],little[i]呢? 用线段树了;#include<stdio.h> #include<string.h> #include<math.h> #include<string> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<list> #include<map> #include<set> using namespace std; const int N=1000010; int n; int a[N]; int big[N],little[N]; int cnt[N*4]; map<int,int>m; int all; void init(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); big[i]=a[i]; } sort(big,big+n); all=unique(big,big+n)-big; for(int i=1;i<=all;i++) m[big[i-1]]=i; for(int i=0;i<n;i++) a[i]=m[a[i]]; } int require(int x,int y,int st,int ed,int i){ if(x>ed || y<st) return 0; if(x<=st && y>=ed) return cnt[i]; int mid=(st+ed)>>1; return require(x,y,st,mid,i*2)+require(x,y,mid+1,ed,i*2+1); } void updata(int x,int st,int ed,int i){ if(x<st || x>ed) return ; cnt[i]++; if(st==ed) return ; int mid=(st+ed)>>1; updata(x,st,mid,i*2); updata(x,mid+1,ed,i*2+1); } void deal_big(){ memset(cnt,0,sizeof(big)); for(int i=0;i<n;i++){ big[i]=require(a[i]+1,all,1,all,1); updata(a[i],1,all,1); } // for(int i=0;i<n;i++) // printf("big==%d\n",big[i]); } void deal_little(){ memset(cnt,0,sizeof(cnt)); for(int i=n-1;i>=0;i--){ little[i]=require(1,a[i]-1,1,all,1); updata(a[i],1,all,1); } // for(int i=0;i<n;i++) // printf("ll=%d\n",little[i]); } void work(){ long long ans=0; for(int i=0;i<n;i++) ans=ans+(1LL)*big[i]*little[i]; cout << ans << endl; } int main() { // freopen("in.in","r",stdin); init(); deal_big(); deal_little(); work(); return 0; }