UVALive 4329 Ping pong

#include <stdio.h>
#include <string.h>

using namespace std;

struct fwtree
{
    int C[101000], n;
    void init(int k){ memset(C, 0, sizeof(C)); n = k; }
    int lowbit(int x) { return x&-x; }
    void add(int x, int d)
    {
        while(x<=n){
            C[x] += d;
            x += lowbit(x);
        }
    }
    long long sum(int x)
    {
        long long ans=0;
        while(x>=1){
            ans += C[x];
            x -= lowbit(x);
        }
        return ans;
    }
};

fwtree f;
int main()
{
    int t, n;
    int maxa;
    long long a[20200][4];
    int p[20200];
    long long ans;

    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        maxa = -1;
        for(int i=1; i<=n; i++){
            scanf("%d", &p[i]);
            if(p[i]>maxa)   maxa = p[i];
        }
        f.init(maxa);
        ans = 0;
        for(int i=1; i<=n; i++){
            f.add(p[i], 1);
            a[i][0] = f.sum(p[i]-1);        //a[i][0]在左边比a[i]小   a[i][1]为在左边比a[i]大
            a[i][1] = i-a[i][0]-1;          //家在i前面的有i-1个
        }
        f.init(maxa);

        for(int i=n; i>=1; i--){
            f.add(p[i], 1);
            a[i][2] = f.sum(p[i]-1);        //a[i][2]在右边比a[i]小   a[i][3]为在右边比a[i]大
            a[i][3] = n-i-a[i][2];
        }
        for(int i=0; i<n; i++)
            ans += a[i][0]*a[i][3] + a[i][1]*a[i][2];
        printf("%lld\n", ans);
    }

    return 0;
}




你可能感兴趣的:(UVALive 4329 Ping pong)