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 }
View Code

 

以上是关于LA4329 Ping pong 树状数组的主要内容,如果未能解决你的问题,请参考以下文章

LA4329 Ping pong 树状数组

[UVALive4329] Ping pong(树状数组,组合)

(4329)Ping pong

树状数组 LA 4329 亚洲赛北京赛区题

LA 4329(树状数组)

poj 3928 Ping pong(树状数组)