题意:训练指南上的例题。大致求1到ai-1有多少个数小于ai;
树状数组,从第一个数开始处理,遇到一个数ai,将C[ai]赋值为1,插入树状数组。便可以快速和。但是bit的最高位要注意是所有输入的数中最大的。开始写成输入的数的个数,wa了好几次。
代码:
#include<iostream>
#include<cstring>
#include<stdio.h>
#define size 100010
using namespace std;
int A[size],C[size],c[size],d[size],vv=0;
int bit(int x)
{
return x&-x;
}
long long sum(int x)
{
long long ret=0;
while(x>0)
{
ret+=C[x];
x-=bit(x);
}
return ret;
}
void add(int x,int n)
{
while(x<=vv)
{
C[x]+=1;
x+=bit(x);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int N;
long long count=0;
scanf("%d",&N);
memset(C,0,sizeof(C));
for(int i=1;i<=N;i++)
{
scanf("%d",&A[i]);
vv=max(vv,A[i]);
}
for(int i=1;i<=N;i++)
{
c[i]=sum(A[i]);
add(A[i],N);
}
memset(C,0,sizeof(C));
for(int i=N;i>=1;i--)
{
d[i]=sum(A[i]);
add(A[i],N);
}
/* for(int i=1;i<=N;i++)
{
cout<<c[i]<<" ";
}
cout<<endl;
for(int i=1;i<=N;i++)
{
cout<<d[i]<<" ";
}
cout<<endl;*/
for(int i=1;i<=N;i++)
{
count+=c[i]*(N-i-d[i])+(i-c[i]-1)*d[i];
}
cout<<count<<endl;
}
return 0;
}