(2012-07-22 14:57:55)
SOJ2497:http://cstest.scu.edu.cn/soj/problem.action?id=2497
这道题实际上是:对于数组s中的每个元素是s[i],找出s[i]左边的元素个数x和右边的元素个数y,然后求Sigma(x*y).
求s[i]左边元素的个数用树状数组,求s[i]右边元素的个数只需将数组s倒过来处理即可。
代码:
#include<iostream>
#include<cstring>
using namespace std;
#define max 32775
int c[max];
int s[50005];
int result[50005];
int lowbit(int x)
{
return x&(x^(x-1));
}
void mod(int i)
{
while(i<max)
{
c[i]++;
i=i+lowbit(i);
}
}
int sum(int i)
{
int SUM=0;
while(i>0)
{
SUM=SUM+c[i];
i=i-lowbit(i);
}
return SUM;
}
long long xiaoye;
int main()
{
int n;
int i;
while(scanf("%d",&n)==1)
{
xiaoye=0;
memset(c,0,sizeof(c));
for(i=1;i<=n;i++)
{
scanf("%d",&s[i]);
mod(s[i]+1);
result[i]=sum(s[i]);
}
memset(c,0,sizeof(c));
for(i=n;i>=1;i--)
{
mod(s[i]+1);
xiaoye+=result[i]*sum(s[i]);
}
printf("%lld\n",xiaoye);
}
return 0;
}