UVALive 4329Ping pong(树状数组)

本文介绍了一种使用树状数组解决UVALive4329Pingpong问题的方法,该问题要求计算可能的比赛组合数量,其中裁判位于两名参赛者之间且技能值介于两者之间。通过维护树状数组来快速查询小于当前裁判技能值的参赛者数量,实现了O(n log n)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值