HDU 2492 Ping pong 树状数组+离散化

来源:互联网 发布:java抓取网页源码 编辑:程序博客网 时间:2024/04/29 12:06
题意:
有n个人要进行乒乓球比赛每一个人都一个技术值,每个人出现的次序就是
他们住的位置,现在要求进行一场比赛,三个人,裁判的技术值在两个人的

中间,位置也在两个人的中间,问一共可以进行这种比赛多少次。

思路:

枚举裁判,用树状数组统计裁判左边比裁判大的 ,也就是逆序数,

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 20000+10#define ll __int64struct ln{    ll v,id;}in[N];ll n;ll a[N];ll c[N];ll b[N];ll cmp(ln x,ln y){    return x.v<y.v;}ll lowbit(ll x){    return x&(-x);}void updata(ll t,ll value){    for(ll i=t;i<=n;i+=lowbit(i))    {        c[i]+=value;    }}ll getSum(ll x){    ll tmp=0;    for(ll i=x;i>=1;i-=lowbit(i))    {        tmp+=c[i];    }    return tmp;}int main(){    ll T;    scanf("%I64d",&T);    while(T--)    {        scanf("%I64d",&n);        for(ll i=1;i<=n;i++)        {            scanf("%I64d",&in[i].v);            in[i].id=i;        }        sort(in+1,in+1+n,cmp);        memset(c,0,sizeof(c));        a[in[1].id]=1;        for(ll i=2;i<=n;i++)        {            if(in[i].v!=in[i-1].v)            a[in[i].id]=i;            else                a[in[i].id]=a[in[i-1].id];        }        for(ll i=1;i<=n;i++)        {            updata(a[i],1);            b[i]=getSum(a[i]-1);        }        ll maxn=0;        for(ll i=2;i<n;i++)        {            maxn+=b[i]*(n-a[i]-(i-1-b[i]));            maxn+=(i-1-b[i])*(a[i]-1-b[i]);        }        printf("%I64d\n",maxn);    }    return 0;}


0 0
原创粉丝点击