当前位置: 代码迷 >> 综合 >> 树状数组_Ping pong
  详细解决方案

树状数组_Ping pong

热度:83   发布时间:2023-11-22 01:28:24.0

题意:给定n个数,a1~an。ai代表每个人的能力值。举办乒乓比赛一次需要三个人,要求中间的人(裁判)的能力值大于其左边的人且小于其右边的人。求一共能举办多少场比赛。

分析:用s1[i]表示第i个人的左边有s1[i]个人的能力值小于ai,用s2[i]表示第i个人的右边有s2[i]个人的能力值小于ai。则以第i个人为裁判可以举办(s1[i]*(n-i-s2[i])+(i-1-s1[i])*s2[i])场比赛。

AC代码

#include <cstdio>
#include <cstring>
using namespace std;
#define lowbit(x) (x&-x)
#define maxn 1000000typedef long long ll;
ll n,a[maxn],c[maxn],d[maxn],s1[maxn],s2[maxn],x[maxn];ll sum(ll x)
{ll res=0;while(x>0){res+=c[x];x-=lowbit(x);}return res;
}
void add(ll x,ll d)
{while(x<=100005){c[x]+=d;x+=lowbit(x);}
}
int main()
{int t;scanf("%d",&t);while(t--){memset(x,0,sizeof(x));scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&a[i]);}memset(c,0,sizeof(c));for(ll i=1;i<=n;i++){add(a[i],1);s1[i]=sum(a[i]-1);}memset(c,0,sizeof(c));for(ll i=n;i>=1;i--){add(a[i],1);s2[i]=sum(a[i]-1);}ll ans=0;for(ll i=2;i<=n;i++){ans+=s1[i]*(n-i-s2[i])+(i-s1[i]-1)*s2[i];}printf("%lld\n",ans);}return 0;
}