uva 1428 - Ping pong(树状数组)

来源:互联网 发布:unity3d vs2017 编辑:程序博客网 时间:2024/05/21 17:29
integers a1, a2...aN follow, indicating the skill rank of each player, in the order of west to east (1$ \le$ai$ \le$100000 , i = 1...N ).

Output

For each test case, output a single line contains an integer, the total number of different games.

Sample Input

13 1 2 3

Sample Output

1

以前没用过树状数组,都是用线段树的,不过既然碰到了这个典型例题,就还是自己手敲一遍吧,树状数组代码确实简单许多。

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;const int INF = 1000000000;const int maxn = 100000 + 5;typedef long long LL;int a[maxn],c[maxn];LL S_left[maxn],B_left[maxn];int n;int lowbit(int x){return x&-x;}LL sum(int x){    LL ret = 0;    while(x > 0){        ret += c[x];        x -= lowbit(x);    }    return ret;}void add(int x){    while(x <= maxn){        c[x] += 1;        x += lowbit(x);    }}int main(){    int t,Max;    scanf("%d",&t);    while(t--){        Max = -1;         memset(c,0,sizeof(c));        scanf("%d",&n);        for(int i = 1;i <= n;i++){            scanf("%d",&a[i]);            add(a[i]);            Max = max(Max,a[i]);            S_left[i] = sum(a[i]-1);            B_left[i] = max((LL)0,sum(Max)-sum(a[i]));        }        LL ans = 0;        for(int i = 1;i <= n;i++){            if(i == 1 || i == n) continue;            ans += S_left[i] * ((sum(Max)-sum(a[i]))-B_left[i]);            ans += B_left[i] * (sum(a[i]-1)-S_left[i]);        }        printf("%lld\n",ans);    }    return 0;}