ACM-ICPC LA 4329 Ping pong(树状数组)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2330

参考资料:《算法入门经典训练指南》刘汝佳 P197

这本书上面写的题目大意、解题思路都写出来了。

在这我贴上自己的

AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3
 4 #define PEOPLE 20001
 5 #define VALUE 100001
 6
 7 typedef long long LL;
 8
 9 int n, a[PEOPLE], amin[PEOPLE], amax[PEOPLE], tree[VALUE];
10
11
12 int lowbit(int x){
13     return x & -x;
14 }
15
16 void add(int x, int d){
17     while(x < VALUE){
18         tree[x] += d;
19         x += lowbit(x);
20     }
21 }
22
23 int sum(int x){
24     int ret = 0;
25     while(x > 0){
26         ret += tree[x];
27         x -= lowbit(x);
28     }
29     return ret;
30 }
31
32 int main(){
33     int t;
34     scanf("%d", &t);
35     while(t--){
36         scanf("%d", &n);
37         for(int i = 1; i <= n; ++i){
38             scanf("%d", &a[i]);
39         }
40
41         memset(tree, 0, sizeof(tree));
42         for(int i = 1; i <= n; ++i){
43             amin[i] = sum(a[i] - 1);//第i个人 统计在第i个人的左边并且技能值小于 的总人数
44             amax[i] = i - 1 - amin[i];//统计 技能值大于第i个人并且在左边的总人数
45             add(a[i], 1);
46         }
47
48         LL ans = 0;
49         memset(tree, 0, sizeof(tree));
50         for(int i = n; i >= 1; --i){
51             LL bmin = sum(a[i] - 1);//统计 技能值小于第i个人并且在第i个人的右边的总人数
52             ans += bmin * amax[i] + (n - i - bmin) * amin[i];
53             add(a[i], 1);
54         }
55         printf("%lld\n", ans);
56     }
57     return 0;
58 }
时间: 2025-01-02 00:19:36

ACM-ICPC LA 4329 Ping pong(树状数组)的相关文章

UVALive 4329 Ping pong (树状数组)

白书上的例题.花了很多时间在找bug上,刚学树状数组,这道题add操作时要注意上限不是n. #include <bits/stdc++.h> using namespace std; #define ll long long const ll maxn = 1e5 + 10; ll C[maxn]; ll n; inline ll lowbit(ll x) { return x & (-x); } ll sum(ll x) { ll ret = 0; while(x > 0) {

HDU 2492 Ping pong (树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492 Ping pong Problem Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To improve their skill rank

uva 1428 - Ping pong(树状数组)

题目链接:uva 1428 - Ping pong 题目大意:一条大街上住着n个乒乓球爱好者,经常组织比赛.每个人都有一个不同的能力值,每场比赛需要3个人,裁判要住在两个选手之间,并且能力值也要在选手之间,问说最多能举行多少场比赛. 解题思路:预处理出bi和ci分别表示说在1~i中能力值比第i个人小的人和i+1~n中能力值比第i个人小的.处理过程用树状数组维护即可. #include <cstdio> #include <cstring> #include <algorith

poj3928 Ping pong 树状数组

http://poj.org/problem?id=3928 Ping pong Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2087   Accepted: 798 Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player

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种比赛. 然后问题就

POJ 3928 Ping pong 树状数组模板题

开始用瓜神说的方法撸了一发线段树,早上没事闲的看了一下树状数组的方法,于是又写了一发树状数组 树状数组: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #includ

POJ-3928 Ping pong(树状数组)

Ping pong Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2985   Accepted: 1104 Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street as a line segment). Each player has a unique skill rank. To i

UVA1428 - Ping pong(树状数组)

题目链接 题目大意:有N个人,每个人都有一个技能值ai,现在要开展乒乓球比赛,要求要有两个选手和一个裁判,要求裁判需要在两名选手的中间而且技能值也是在两名选手的中间,问可以开展多少场比赛. 解题思路:对于第i个选手当裁判的话,设它前面位置的选手有ci个技能值比它低的,那么就有i - 1 - ci个比它高的,对于第i选手后面的位置,同样有di个技能值比它低的,那么就有N - i - di个比它高的.组合一下:ci?(N - i - di) + (i - 1 - ci) ? di.那么对于ci的值,

LA 4329 Ping pong

#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int Max=20010; const int inf=100000; int lm[Max],rm[Max],a[Max],c[Max*10]; int n; long long lowbit(long long x) { return x&-x; } int sum(long long x,

BIT LA 4329 Ping pong

题目传送门 题意:训练指南P197 分析:枚举裁判的位置,用树状数组来得知前面比它小的和大的以及后面比它小的和大的,然后O (n)累加小 * 大 + 大 * 小 就可以了 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; const int M = 2e4 + 5; struct BIT { int c[N], sz; void init(int n) { mem