这次还是想了很久,在床上时突然间想通了,不过写得不是太慢了,写代码总是出现一些低级失误,这雨真有点无语~~~~~
#include<stdio.h> #define N 100024 struct node{ int l; int r; int sum; }; node tree1[3*N]; node tree2[3*N]; int count[N]; int count1[N]; int arr[N]; void buid_tree(node *p,int k,int left,int right) { int L,R;int x; int mid;/*printf("(%d %d %d)",k,left,right);scanf("%d",&x);*/ (p+k)->l = left; (p+k)->r = right; if((p+k)->r-(p+k)->l == 1){ (p+k)->sum = 0; return ; } L = 2*k; R = L+1; mid = (left+right)/2; buid_tree(p,L,left,mid); buid_tree(p,R,mid,right); (p+k)->sum = (p+L)->sum+(p+R)->sum; return ; } int tree_search(node *p,int k,int left,int right) { int ls = 0,rs = 0; int L,R; int mid; if(left <= (p+k)->l && right >= (p+k)->r) return (p+k)->sum; L = 2*k; R = L+1; mid = ((p+k)->l+(p+k)->r)/2; if(left < mid) ls = tree_search(p,L,left,right); if(right > mid) rs = tree_search(p,R,left,right); return ls+rs; } void tree_insert(node *p,int k,int left,int right) { int mid; int L,R; if(left <= (p+k)->l && right >= (p+k)->r){ (p+k)->sum++; return ; } L = 2*k; R = L+1; mid = ((p+k)->l+(p+k)->r)/2; if(left < mid) tree_insert(p,L,left,right); if(right > mid) tree_insert(p,R,left,right); (p+k)->sum = (p+L)->sum + (p+R)->sum; return ; } int main() { int i,j; int tcase; int n; int x; __int64 ans; scanf("%d",&tcase); while(tcase--){ ans = 0; scanf("%d",&n); buid_tree(tree1,1,0,N+1); for(i = 1;i <= n;i++){ scanf("%d",&arr[i]); count[i] = tree_search(tree1,1,0,arr[i]); tree_insert(tree1,1,arr[i],arr[i]+1); } buid_tree(tree2,1,0,N+1); for( i = n;i >= 1;i--){ count1[i] = tree_search(tree2,1,0,arr[i]); tree_insert(tree2,1,arr[i],arr[i]+1); } for(i = 1;i <= n;i++){ ans += (__int64)count[i]*(__int64)((n-i)-count1[i]); ans += (__int64)(i-1-count[i])*(__int64)count1[i]; } printf("%I64d/n",ans); } return 0; }