LA 4329 - Ping pong(树状数组)
2015-09-22 21:06
387 查看
题目链接
该题非常经典,我们可以枚举每一个当裁判的人,将问题转化为求某个数左边和右边比他小的数有多少。
怎么办呢?我们先来求某个数左边比他技能值小的数字个数c[i],d[i]数组类似
我们知道树状数组可以快速求前缀和单点修改。 那么我们不妨将技能值作为bit数组下标,那么我们只需要从左向右扫一遍,每次单点更新,将当前技能值a[i]的个数+1,那么sum(a[i]-1)就是比当前能力值小的数字个数了。
细节参见代码:
该题非常经典,我们可以枚举每一个当裁判的人,将问题转化为求某个数左边和右边比他小的数有多少。
怎么办呢?我们先来求某个数左边比他技能值小的数字个数c[i],d[i]数组类似
我们知道树状数组可以快速求前缀和单点修改。 那么我们不妨将技能值作为bit数组下标,那么我们只需要从左向右扫一遍,每次单点更新,将当前技能值a[i]的个数+1,那么sum(a[i]-1)就是比当前能力值小的数字个数了。
细节参见代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<list> #include<cmath> #include<set> #include<queue> using namespace std; typedef long long ll; const int maxn = 20000 + 3; const int maxm = 100000 + 5; int T,n,m,l,r,a[maxn],c[maxn],x[maxm],d[maxn],bit[maxm+5]; ll sum(int x) { ll ret = 0; while(x > 0) { ret += bit[x]; x -= (x & -x); } return ret; } void add(int x,int d) { while(x <= maxm) { bit[x] += d; x += (x & -x); } } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); memset(bit,0,sizeof(bit)); memset(x,0,sizeof(x)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { add(a[i],1); c[i] = sum(a[i]-1); } memset(bit,0,sizeof(bit)); memset(x,0,sizeof(x)); for(int i=n;i>=1;i--) { add(a[i],1); d[i] = sum(a[i]-1); } ll ans = 0; for(int i=1;i<=n;i++) ans += (c[i]*(n-i-d[i])+d[i]*(i-c[i]-1)); printf("%lld\n",ans); } return 0; }
相关文章推荐
- 垃圾收集算法
- volatile的特性
- hdu5452 || 沈阳网络赛1003题 最近公共祖先问题
- asp.net判断session过期
- hdu1010(dfs加剪枝)
- 树链剖分——边上权值和
- Android性能测试工具列表
- JAVA_SE基础——29.构造函数
- (4.4.1.9) Android内存泄漏简介
- git版本退回笔记
- c#网络编程学习笔记01_委托
- web.xml 详细介绍
- 每天一个css text-indent
- apache kafka系列之在zookeeper中存储结构
- Gephi 源码构建过程
- 使用软引用解决Handler内存泄露和显示Popupwindow、Dialog时提示"Unable to add Window-token is null"的问题
- DP总结(content)
- CVBS
- [基本实验] PHP二次渲染
- 华为将操作系统“装入”海尔