题意:
一串数字 问 有几种这样的组合(x,y,z)使得x>y>z或x<y<z y在x数字后面z在y后面 题目中每种数字是唯一的
思路:
对于一个数字 比如 f 它计算出的ans值为
( beforef.lessthanf * afterf.biggerthanf )+( beforef.biggerthanf * afterf.lessthanf )
易知 beforef.biggerthanf = locationf - 1 - beforef.lessthanf 同理after
则式子可化简为
( beforef.lessthanf * ( n - locationf - afterf.lessthanf ) )+( ( locationf - 1 - beforef.lessthanf ) * afterf.lessthanf )
如果我们从小到大的处理每个数字 那么可知当前处理的数字是当前序列中最大的
则 afterf.lessthanf = nowallnumber - beforef.lessthanf
那么式子中将只出现一个未知数 也就是说我们只需要知道当前位置前有几个小于自己即可
因此用树状数组维护
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 20010
#define lowbit(x) (x&(-x))
int t,n;
int a[N];
__int64 ans;
struct person
{
int id,val;
bool operator<(const person fa) const
{
return val<fa.val;
}
}f[N];
void add(int x)
{
while(x<=n)
{
a[x]+=1;
x+=lowbit(x);
}
}
int sum(int x)
{
int res=0;
while(x)
{
res+=a[x];
x-=lowbit(x);
}
return res;
}
int main()
{
int i,ls,lb,rs,rb,id;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
f[i].id=i;
scanf("%d",&f[i].val);
}
sort(f+1,f+1+n);
memset(a,0,sizeof(a));
ans=0;
for(i=1;i<=n;i++)
{
id=f[i].id;
ls=sum(id);
lb=id-ls-1;
rs=sum(n)-ls;
rb=n-id-rs;
ans+=ls*rb;
ans+=lb*rs;
add(id);
}
printf("%I64d\n",ans);
}
return 0;
}