hdu 4000 - Fruit Ninja(树状数组)

来源:互联网 发布:jhene aiko 知乎 编辑:程序博客网 时间:2024/04/29 23:22

题意:

给定一个1到n的排列,输出三元组(x,y,z) (满足条件x<z<y)的个数。

思路:

建立树状数组,对于每个位置都求出前面比a[i]小的数字的个数L,好后面比a[i]大的数字的个数R, 则有该位置作为开始的的满足条件的三元组包含在R(R-1)个中,当然其中参杂着(x,y,z)(x<y<z),这样的三元组可以有L*R得到,二者之差便是答案,

代码如下:

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <queue>#include <stack>#include <list>#include <vector>#include <map>#include <algorithm>#define LL long long#define LLU unsigned long long#define INF 0x7fffffff#define MOD 100000007using namespace std;#define lowbit(x) x&-x#define M 100005int c[M];LL sum(int x){    LL ret = 0;    while(x>0)    {        ret += c[x];        x -= lowbit(x);    }    return ret;}void add(int x, int n){    while(x<=n)    {        c[x] += 1;        x += lowbit(x);    }}int main (){    int t, n, x, k = 0;    scanf("%d",&t);    while(t--)    {        scanf("%d", &n);        LL ans = 0;        memset(c,0,sizeof(c));        for(int i = 1; i <= n; ++i)        {            scanf("%d",&x);            add(x, n);            LL l = sum(x-1);            LL r = n - i - x + l + 1;            ans -= l*r;            if(r>=2) ans += r*(r-1)/2;        }        printf("Case #%d: %I64d\n",++k, ans%MOD);    }    return 0;}