http://codeforces.com/contest/459/problem/D
题意:给你n个数,然后统计多少组(i,j)使得f(1,i,ai)>f(j,n,aj);
思路:先从左往右统计f(1,i,ai)记录在b[i],然后从右往左统计f(j,n,aj)记录在c[i],然后利用树状数组统计个数即可。
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #include <queue> 6 #include <map> 7 #include <algorithm> 8 #define maxn 1000010 9 #define ll long long 10 using namespace std; 11 const int inf=1<<30; 12 13 int n,m; 14 ll a[maxn]; 15 ll b[maxn]; 16 ll c[maxn]; 17 ll y[maxn]; 18 ll xx[maxn]; 19 ll vis1[maxn],vis2[maxn]; 20 21 int lowbit(int x) 22 { 23 return x&(-x); 24 } 25 26 void Insert(int x,ll val) 27 { 28 while(x<maxn) 29 { 30 y[x]+=val; 31 x+=lowbit(x); 32 } 33 } 34 35 ll Getsum(int x) 36 { 37 ll ans=0; 38 while(x>0) 39 { 40 ans+=y[x]; 41 x-=lowbit(x); 42 } 43 return ans; 44 } 45 46 int main() 47 { 48 scanf("%d",&n); 49 for(int i=1; i<=n; i++) 50 { 51 scanf("%lld",&a[i]); 52 xx[i]=a[i]; 53 } 54 sort(xx+1,xx+1+n); 55 int cnt=1; 56 for(int i=2; i<=n; i++) 57 { 58 if(xx[i-1]!=xx[i]) 59 { 60 xx[++cnt]=xx[i]; 61 } 62 } 63 for(int i=1; i<=n; i++) 64 { 65 int pos=lower_bound(xx+1,xx+cnt+1,a[i])-xx; 66 vis1[pos]++; 67 b[i]=vis1[pos]; 68 } 69 for(int i=n; i>=1; i--) 70 { 71 int pos=lower_bound(xx+1,xx+cnt+1,a[i])-xx; 72 vis2[pos]++; 73 c[i]=vis2[pos]; 74 } 75 ll ans=0; 76 for(int i=n; i>=1; i--) 77 { 78 ans+=Getsum(b[i]-1); 79 Insert(c[i],1); 80 } 81 printf("%I64d ",ans); 82 return 0; 83 }