POJ-3928-Ping pong

来源:互联网 发布:淘宝上开刃刀 编辑:程序博客网 时间:2024/05/16 19:01

这个题要求计算出有最多可能有多少场比赛,参考了下别人的代码,然后不得不佩服这种方法的巧妙,自己重新写了一下

代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define MAX 40001using namespace std;struct node {    int val;    int id;    bool operator < (const node &a) const    {return val<a.val;    }}a[MAX];    int n,c[2][MAX],posa[MAX],posb[MAX];int lowbit(int x){    return x&(-x);}void add(int t,int x,int val){    while(x<=n)    {c[t][x]+=val;x+=lowbit(x);    }}int sum(int t,int x){    int sum=0;    while(x>0)    {sum+=c[t][x];x-=lowbit(x);    }    return sum;}int main(){    int cas;    scanf("%d",&cas);    while(cas--)    {scanf("%d",&n);for(int i=1;i<=n;i++){    scanf("%d",&a[i].val);    a[i].id=i;}sort(a+1,a+n+1);memset(c,0,sizeof(c));memset(posa,0,sizeof(posa));memset(posb,0,sizeof(posb));for(int i=1;i<=n;i++)    posa[a[i].id]=i;for(int i=1;i<=n;i++)    posb[a[i].id]=n-i+1;long long ans=0;for(int i=1;i<=n;i++){    int ita=sum(0,posa[i]);    add(0,posa[i],1);    ans+=ita*(n-posa[i]-(i-ita-1));    ita=sum(1,posb[i]);    add(1,posb[i],1);    ans+=ita*(n-posb[i]-(i-ita-1));}printf("%lld\n",ans);    }    return 0;}