大体题意:

街道上住着n 个 人,每个人都喜欢打乒乓球,他们之间会互相切磋,那组织一场乒乓球比赛需要三个人,一个裁判,两个运动员,要求裁判的能力值要介于两个运动员之间,并且位置也在他们之间,问最后有多少种选法?

思路:

输入完n 个数后,统计  在a[i]左边比a[i]小的个数 有sml[i]个,那么大的就有i-1-sml[i]个,在统计右边比a[i]小的个数 smr[i]个,那么大的个数就有n-i-smr[i]个!

最终答案就是遍历裁判即可!裁判从2~n  依次遍历即可!

题目比较简单,具体不说了。

详细见代码

注意 用long long  还有树状数组  x <= 范围尽可能大,莫名的wa!!!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
int a[maxn],sml[maxn],smr[maxn],c[maxn];
int n;
int lowbit(int x){
    return x&-x;
}
void add(int x,int d){
    while(x <= maxn){
        c[x] += d;
        x += lowbit(x);

    }
}
int sum(int x){
    int ans = 0;
    while(x > 0){
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for (int i = 1; i <= n; ++i){
            scanf("%d",&a[i]);
        }
        memset(c,0,sizeof c);
        for (int i = 1; i <= n; ++i){
            add(a[i],1);
            sml[i] = sum(a[i]-1);
        }
        memset(c,0,sizeof c);
        for (int i = n; i >= 1; --i){
            add(a[i],1);
            smr[i] = sum(a[i]-1);
        }
        ll ans = 0ll;
        for (int i = 2 ; i < n; ++i){
            ans += (ll)sml[i]*(ll)(n-i-smr[i]) + (ll)smr[i] * (ll)(i-1-sml[i]);
        }
        printf("%lld\n",ans);

    }
    return 0;
}