hdu 2492 Ping pong 树状数组 求逆序数

来源:互联网 发布:淘宝商学院网址 编辑:程序博客网 时间:2024/05/14 11:45

原题链接:点击打开链接

题意:有t组数据,每行数据的第一个数 n 表示有n个人,每个位置上的数据代表选手的技能值,现在要三个人组队,按照位置的顺序,三个人中间的人是裁判,两边的选手,裁判的技能值要跟位置一样位于两位选手之间。

思路:一个点一个点的判断,求该点点左边比它大的数的个数,右边比它小的数的个数,相乘就是一部分的解,再求左边比它小的数的个数,右边比它大的数的个数,相乘得另一部分的解,两部分的解相加就是要求的结果 。

code:

#include<stdio.h>#include<string.h>#define MAX 100100int n,c[MAX],l1[MAX],l2[MAX],r1[MAX],r2[MAX],a[MAX];int flag;int Lowbit(int k){return (k&-k);}void update(int pos,int num){while(pos<MAX)//是MAX 而不是 n    {c[pos]+=num;pos+=Lowbit(pos);}}int sum(int pos){int s=0;while(pos>0){s+=c[pos];pos-=Lowbit(pos);}return s;}int main(){   // freopen("i.txt","r",stdin);       int i,t;   scanf("%d",&t);   while(t--)   {   memset(c,0,sizeof(c));   scanf("%d",&n);   for(i=1;i<=n;i++)//求左边比该点技能值大的数的个数,小的数的个数   {   scanf("%d",&a[i]);   l1[i]=sum(a[i]); //输入的i个数中 有 sum(a[i]) 个比a[i]小   l2[i]=i-1-l1[i]; //输入的i个数中 有 i-1-sum(a[i]) 个比a[i]大   update(a[i],1);   }   memset(c,0,sizeof(c));   int j=1;//代表现在输入的数的个数   for(i=n;i>=1;i--,j++)//求右边比该点技能值大的数的个数,小的数的个数   { r1[i]=sum(a[i]);//输入a[i]后 输入的那些数中有 sum(a[i]) 个比a[i]小的 r2[i]=j-1-r1[i]; //输入a[i]后输入的那些数中有 j-1-sum(a[i] 个比a[i]大的 update(a[i],1);   }   __int64 ans=0;   for(i=1;i<=n;i++)  ans+=l1[i]*r2[i]+l2[i]*r1[i];   printf("%I64d\n",ans);   }    return 0;}





0 0
原创粉丝点击