UVALA 4329 - Ping pong 树状数组+组合原理

来源:互联网 发布:网络运维绩效考核 编辑:程序博客网 时间:2024/06/04 21:48

点击打开题目链接 UVALA 4329


题意与分析:

代码:

#include <cstdio>#include <iostream>#include <cstring>using namespace std;const int MAXN = 20000 + 10;const int MAXM = 100000 +10;int num[MAXN];int c[MAXN], d[MAXN], x[MAXM];//x 的二进制表达式中最右边的1所对应的值int lobit(int x){    return x & -x;}//前缀和int sum(int k){    int ret = 0;    while(k > 0)    {        ret += x[k];        k -= lobit(k);    }    return ret;}//更新 x 数组void add(int k){    while (k <= 100000)    {        x[k] += 1;        k += lobit(k);    }}int main(){    int t, n;    scanf("%d", &t);    while (t--)    {        scanf("%d", &n);        for (int i = 1; i <= n; i++)        {            scanf("%d", &num[i]);        }        memset(x, 0, sizeof(x));        for (int i = 1; i <= n; i++)    //正序求c[i]        {            add(num[i]);            c[i] = sum(num[i] - 1);        }        memset(x, 0, sizeof(x));        for (int i = n; i >= 1; i--)    //逆序求d[i]        {            add(num[i]);            d[i] = sum(num[i] - 1);        }        long long ans = 0;        for (int i = 1; i <= n; i++)        {            ans += (long long)c[i] * (n - i - d[i]) + d[i] * (i - 1 - c[i]);        }        printf("%lld\n", ans);    }    return 0;}


0 0