HDU 2492 Ping pong (树状数组)

来源:互联网 发布:java中的get和set方法 编辑:程序博客网 时间:2024/04/29 03:47

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492

题       意:给你一组数据,求出a<b<c的情况共有多少种。

思       路:先把所有的数当做b来处理,采用树状数组找出x1左边比他小的数,x2左边比他大的数,y1右边比他小的数,y2右边比他大的数。

                    得出满足a<b<c的数共有x1*y2+x2*y1组。

代码如下:

#include <iostream>using namespace std;#include <string.h>#include <stdio.h>#include <queue>#include <algorithm>#define m1  200000int c[m1],vis[m1];int lowbit( int t ){    return t & (-t);}void update( int pos, int num ){    while( pos < m1 )//pos应小于数组的去做范围    {        c[pos]+= num;        pos += lowbit(pos);    }}int sum( int endx ){    int s = 0;    while( endx > 0 )    {        s += c[endx];        endx -= lowbit(endx);    }    return s;}int x1[m1],x2[m1],y1[m1],y2[m1];int main(){    int T;    scanf ( "%d", &T );    while( T-- )    {       memset(c, 0, sizeof(c) );       int  n;       scanf ( "%d", &n );       for( int i = 1; i <= n; i ++ )       {           scanf ( "%d", &vis[i] );           int k1;           k1=sum(vis[i]);           x1[i]=k1;//座边比他小的数有k1个           x2[i]=i-1-k1;//他的座边共有i个数,右边比他大的数有i-1-k1个           update(vis[i],1);       }       memset(c, 0, sizeof(c) );       int j = 1;       for( int i = n; i > 0; i -- ,j ++ )       {           int k1;           k1=sum(vis[i]);           y1[i]=k1;//右边比他小的数有k1个           y2[i]=j-1-k1;//他的右边共有j个数,右边比他大的数有j-1-k1个           update(vis[i],1);       }       __int64 ans = 0;       for ( int i = 1; i <= n; i ++ )       {           ans += (x1[i]*y2[i])+(x2[i]*y1[i]);       }       printf("%I64d\n",ans);    }    return 0;}


 

 

0 0