题目大意:一条大街住着n个乒乓爱好者,经常组织切磋技术,每个人有一个不同的技能值ai.每场比赛要3个人,两选手,一裁判.裁判要住在两选手之间,技能也是位于其之间.问能组织多少种比赛.
题目思路:假设第i个人当裁判,假设a1到ai1中有m1[i]个比ai小,那么就有(i-1)-m1[i]个比ai大.同理m2[i]表示ai+1到an中比ai小的数.那么i当裁判能组织m1[i]*(n-i-m2[i]) + (i-m1[i]-1)*m2[i]种比赛.
代码如下:
#include <stdio.h>
#include <string.h>
const int maxn = 100005;
int c[maxn];
int a[20005];
int m1[20005], m2[20005];
int lowbit(int x){
return x&(-x);
}
int sum(int x){
int ret = 0;
while(x > 0){
ret += c[x];
x -= lowbit(x);
}
return ret;
}
void add(int x, int d){
while(x < maxn){
c[x] += d;
x += lowbit(x);
}
}
int main(){
int t, n;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
memset(c, 0, sizeof(c));
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
m1[i] = sum(a[i]);
add(a[i], 1);
}
memset(c, 0, sizeof(c));
for(int i = n; i >= 1; i--){
m2[i] = sum(a[i]);
add(a[i], 1);
}
long long ans = 0;
for(int i = 1; i <= n; i++){
ans += (long long)m1[i]*(n-i-m2[i]) + (long long)(i-m1[i]-1)*m2[i];
}
printf("%lld\n", ans);
}
return 0;
}