HDU2491 Priest John's Busiest Day
2015-08-17 23:07
363 查看
题目链接
题意:
有n个人要进行乒乓球比赛,每个人都一个能力值,每个人出现的次序就是他们住的位置
现在要求进行一场比赛,三个人,裁判的能力值在两个选手之间,住的位置也在两个人的之间
问这种比赛一共可以进行多少次
思路:
用树状数组做,否则TLE,先从左到右扫一遍,计算每点左边大的个数和小的个数,
再从右到左扫一遍,计算每点右边大和小的个数,然后交叉相乘取和就可以了
代码如下:
题意:
有n个人要进行乒乓球比赛,每个人都一个能力值,每个人出现的次序就是他们住的位置
现在要求进行一场比赛,三个人,裁判的能力值在两个选手之间,住的位置也在两个人的之间
问这种比赛一共可以进行多少次
思路:
用树状数组做,否则TLE,先从左到右扫一遍,计算每点左边大的个数和小的个数,
再从右到左扫一遍,计算每点右边大和小的个数,然后交叉相乘取和就可以了
代码如下:
#include<cstdio> #include<cstring> #include<string> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N = 1e5+10; int n; int p , c , li , la , ri , ra ; inline int Lowbit(int x){ return x&(-x); } void change(int u, int x) { while(u < N) { c[u] += x; u += Lowbit(u); } } int get_sum(int x) { int ans = 0; for(int i = x; i > 0; i -= Lowbit(i)) { ans += c[i]; } return ans; } int main() { int t; scanf("%d", &t); while(t--) { memset(c, 0, sizeof(c)); scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &p[i]); int cnt = get_sum(p[i]); li[i] = cnt; // i点左边比它小的 la[i] = i - cnt - 1; //i点左边比它大的 change(p[i], 1); } memset(c, 0, sizeof(c)); for(int i = n; i > 0; i--) { int cnt = get_sum(p[i]); ri[i] = cnt; // i点右边比它小的 ra[i] = n - i - cnt; //i点右边比它大的 change(p[i], 1); } ll ans = 0; for(int i = 1; i <= n; i++) { ans += li[i] * ra[i] + la[i] * ri[i]; } printf("%I64d\n", ans); } return 0; }
相关文章推荐
- 九度 Online Judge 算法 刷题 题目1158:买房子
- 创建git仓库和初始化仓库
- 孤儿进程与僵尸进程
- Prim算法与Dijkstra算法的联系与区别
- 秋季养生多吃三种鱼
- USACO CHAPTER 1 1.1 Ride 水题
- TimesTen_重建业务日志表
- iOS编程:学习篇(十一)
- 常用的网络开发库
- 剑指Offer面试题:2.二维数组中的查找
- TCP相关知识
- 逆波兰表达式实现计算器(附c++代码)
- JLink v8克隆版破解向导
- mac git+shell实现快速提交push
- HDU 4700 Flow(瓶颈生成树)
- crazyflie2.0状态记录
- Oracle 学习之性能优化(二)游标
- tips android 汇总
- Eclipse中修改Maven配置
- POJ3667--Hotel(区间合并)