LA4329 Ping pong 树状数组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LA4329 Ping pong 树状数组相关的知识,希望对你有一定的参考价值。
题意:
一条大街上住着n个乒乓球爱好者,经常组织比赛切磋技术。每个人都有一个能力值a[i]。
每场比赛需要三个人:两名选手,一名裁判。他们有个奇怪的约定,裁判必须住在两名选手之间,而裁判的能力值也必须在两名选手之间。
问一共能组织多少种比赛。
分析:
考虑第i个人,假设a1到ai-1中有ci个比ai小,那么就有(i-1)-ci个比ai大;
同理,如果ai+1到an中有di个比ai小,那么就有(n-i)-di个比ai大。
i当裁判就有:ci * (n-i-di) + (i-1-ci)*di种比赛。
然后问题就转化为了计算数组c和数组d。这样的话就很容易想到使用树状数组去计算前缀和。
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8 #include<vector> 9 #include<cstring> 10 #include<stack> 11 #include<cmath> 12 #include<queue> 13 #include <bits/stdc++.h> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define ll long long 17 #define clc(a,b) memset(a,b,sizeof(a)) 18 19 inline int lowbit(int x) 20 { 21 return x&-x; 22 } 23 24 struct bit 25 { 26 int n; 27 vector<int>C; 28 29 void resise(int n) 30 { 31 this->n=n; 32 C.resize(n); 33 } 34 void clear() 35 { 36 fill(C.begin(),C.end(),0); 37 } 38 int sum(int x) 39 { 40 int ret=0; 41 while(x>0) 42 { 43 ret+=C[x]; 44 x-=lowbit(x); 45 } 46 return ret; 47 } 48 void add(int x,int d) 49 { 50 while(x<=n) 51 { 52 C[x]+=d; 53 x+=lowbit(x); 54 } 55 } 56 }; 57 58 const int maxn=20000+5; 59 int n,a[maxn],c[maxn],d[maxn]; 60 61 bit f; 62 63 int main() 64 { 65 int t; 66 scanf("%d",&t); 67 while(t--) 68 { 69 scanf("%d",&n); 70 int maxa=0; 71 for(int i=1; i<=n; i++) 72 { 73 scanf("%d",&a[i]); 74 maxa=max(maxa,a[i]); 75 } 76 f.resise(maxa); 77 f.clear(); 78 for(int i=1; i<=n; i++) 79 { 80 f.add(a[i],1); 81 c[i]=f.sum(a[i]-1); 82 } 83 f.clear(); 84 for(int i=n; i>=1; i--) 85 { 86 f.add(a[i],1); 87 d[i]=f.sum(a[i]-1); 88 } 89 ll ans=0; 90 for(int i=1; i<=n; i++) 91 ans+=(ll)c[i]*(n-i-d[i])+(ll)d[i]*(i-c[i]-1); 92 printf("%lld\n",ans); 93 } 94 return 0; 95 }
以上是关于LA4329 Ping pong 树状数组的主要内容,如果未能解决你的问题,请参考以下文章