对于原数据a[],树状数组c[],c[n]表示的段是c[n]=a[n-2^k+1]+....a[n],其中k是n在二进制下末尾0的个数,比如n=6(110)对于的k就是1;
//树状数组来做;
#include <iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=100005;
const int maxm=20005;
int c[maxn];
int rank1[maxm];
int d[maxn];
int left1[maxm];
int right1[maxm];
int n;
int lowbit(int x)
{
return (x&-x);
}
void update(int x,int c1)
{
int i;
//cout<<"hah"<<" ";
for(i=x;i<=n;i+=lowbit(i))
{
c[i]+=c1;
}
}
int getsum(int x)
{
int i;
int ans=0;
for(i=x;i>0;i-=lowbit(i))
{
ans+=c[i];
}
return ans;
}
int main()
{
int case1;
scanf("%d",&case1);
while(case1--)
{
memset(c,0,sizeof(c));
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&rank1[i]);
d[rank1[i]]=i;
}
sort(rank1,rank1+n);//这一步也很关键
for(i=0;i<n;i++)
{
rank1[i]=d[rank1[i]]+1;
}
memset(left1,0,sizeof(left1));
memset(right1,0,sizeof(right1));
for(i=0;i<n;i++)
{
// cout<<"haha"<<endl;
left1[i]=getsum(rank1[i]);//这一步是关键
update(rank1[i],1);
}
//cout<<121<<endl;
memset(c,0,sizeof(c));
for(i=n-1;i>=0;i--)
{
right1[i]=getsum(rank1[i]);
update(rank1[i],1);
}
long long ans=0;
for(i=0;i<n;i++)
{
ans+=left1[i]*(n-i-1-right1[i])+(i-left1[i])*right1[i];
}
printf("%lld\n",ans);
}
return 0;
}
POJ3928
最新推荐文章于 2018-12-27 21:50:00 发布