UVALive 4329Ping pong(树状数组)

来源:互联网 发布:网络监控能看到多久的 编辑:程序博客网 时间:2024/05/17 05:11

UVALive 4329Ping pong

题意:
一条大街上住着 n 个乒乓球爱好者,经常组织比赛切磋技术。

每个人都有一个不同的技能值 ai。每场比赛需要 3 个人:两名选手,一名裁判。

他们有一个奇怪的规定,即裁判必须住在两名选手的中间,并且技能值也在两名选手之间。问一共能组织多少种比赛。

我的:
因为n是10^5,所以以中间的值作为裁判,再遍历两端找到比该点大,小的个数,相乘之后相加的话就是(n^2)的复杂度,会超时的。
所以就利用树状数组,因为树状数组的复杂度是logn,所以总的复杂度就是nlogn,是不会超时的。
树状数组是利用了把数组里面的值当做tree数组里面的下标,然后get是求出i之前有多少值比a[i]小的数。

这里引用一下我哥们写的一个博客,感觉写的挺好的,力挺

我的:

#include<iostream>#include<string>#include<cstdio>#include<cmath>#include<map>#include<algorithm>#include<cstring>using namespace std;const int maxn=100000+10;#define PI acos(-1.0)int tree[maxn];inline int lowbit(int x){    return x&(-x);}void add(int x,int value){    for(int i=x;i<=maxn;i+=lowbit(i))    {        tree[i]+=value;    }}int get(int x){    int sum=0;    for(int i=x;i>0;i-=lowbit(i))    {        sum+=tree[i];    }    return sum;}int main(){    int n;    int Tcase;    scanf("%d",&Tcase);    while(Tcase--)    {        scanf("%d",&n);        int a[maxn];        for(int i=0;i<n;++i)            scanf("%d",&a[i]);        int b[maxn];        int c[maxn];        memset(tree,0,sizeof(tree));        for(int i=0;i<n;++i)        {            b[i]=get(a[i]);//找到下标i的左边比a[i]小的个数            add(a[i],1);        }        memset(tree,0,sizeof(tree));        for(int i=n-1;i>=0;--i)        {            c[i]=get(a[i]);//找到下标i的右边比a[i]小的个数            add(a[i],1);        }        long long ans=0;//        for(int i=0;i<n;i++)//        {//            cout<<b[i]<<" ";//        }//        cout<<endl;//        for(int i=0;i<n;i++)//            cout<<c[i]<<" ";        for(int i=0;i<n;++i)        {            ans+=b[i]*(n-1-i-c[i]);            ans+=c[i]*(i-b[i]);        }        printf("%lld\n",ans);   }   return 0;}
0 0
原创粉丝点击