这个题对于每个ai求出ci(ai之前比它小的数有多少个),再求出di(ai之后比它小的数有多少个),通过ci,di,能求出ai之前比它大的数和ai之后比它大的数,分别相乘求和.
书上说的xj表示ai=j存在,其实xi应该表示ai之前的数的和。代码写了两遍,思路一样,但是不知道为什么第一遍错了= 。 =
/*************************************************************************
> File Name: pp.cpp
> Author: bxf
> Mail: bbb546754186@vip.qq.com
> Created Time: 2014年08月08日 星期五 17时41分37秒
************************************************************************/
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <set>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm>
#define INF 0xfffffff
#define maxn 20000 + 10
#define ll long long
using namespace std;
int a[maxn], c[maxn], d[maxn];
int x[100010];
int maxx;
void add(int i)
{
while(i <= maxx)
{
x[i]++;
i += i&-i;
}
}
int sum(int i)
{
int ans = 0;
while(i > 0)
{
ans += x[i];
i -= i&-i;
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
maxx = 0;
memset(c, 0, sizeof(c));
memset(d, 0, sizeof(d));
memset(x, 0, sizeof(x));
for(int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
maxx = max(maxx, a[i]);
}
add(a[1]);
for(int i = 2; i <= n-1; ++i)
{
c[i] = sum(a[i]);
add(a[i]);
}
memset(x, 0, sizeof(x));
add(a[n]);
for(int i = n-1; i >= 2; --i)
{
d[i] = sum(a[i]);
add(a[i]);
}
ll ans = 0;
for(int i = 2; i <= n-1; ++i)
ans += (ll)d[i]*(i-1-c[i]) + (ll)c[i]*(n-i-d[i]);
printf("%lld\n", ans);
}
return 0;
}