Problem A
3 3 3 2 1 3 2 3 1 4 10 8 3 1
1 0 4
/*将原来的数据按照从小到大一次hash成1--n, 然后每次计算[1,i]中比a[i]小的元素的个数x 每次ans增加的值就是 (i-1-x)*(a[i]-1-x),最后输出ans的值即可*/ #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<ctime> #define N 1000006 using namespace std; struct data { int num,id; } b[N]; int a[N]; int sum[N]; void qsort(int st,int en) //对输入的数据进行排序 { srand((unsigned)time(NULL)); //产生一个st到en的随机数 ll int ll=rand()%(en-st)+st; int i=st,j=en; b[0]=b[ll]; b[ll]=b[st]; b[st]=b[0]; while(i<j) { while(i<j && b[0].num<=b[j].num) j--; if(i<j) { b[i]=b[j]; i++; } while(i<j && b[0].num>=b[i].num) i++; if(i<j) { b[j]=b[i]; j--; } } b[i]=b[0]; if(st<i-1) qsort(st,i-1); if(i+1<en) qsort(i+1,en); } __int64 get_sum(int *a,int pos) //求和 { __int64 temp=0; while(pos>0) { temp+=a[pos]; pos-=pos&(-pos); } return temp; } void update(int *a,int pos,int k) //更新 { while(pos<N) { a[pos]+=k; pos+=pos&(-pos); } } int main() { int t,n; scanf("%d",&t); while(t--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(sum,0,sizeof(sum)); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); b[i].num=a[i]; b[i].id=i; } qsort(1,n); for(int i=1;i<=n;i++) a[b[i].id]=i; //将原来的数据按照从小到大hash成1--n __int64 ans=0; for(int i=1;i<=n;i++) { __int64 x=get_sum(sum,a[i]); //找到[1,i]中,比a[i]小的元素的个数 ans+=(i-1-x)*(a[i]-1-x); update(sum,a[i],1); //将a[i]的元素的个数增加1个 } printf("%I64d\n",ans); } return 0; }