树状数组 LA 4329 亚洲赛北京赛区题
复习下树状数组
还是蛮有意思的一道题:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=501&page=show_problem&problem=4174
学到几点:
1、树状数组C[i]的构建,一则c[i]=s[i]-s[i-lowbit(i)];这是一直用的做法。如今学到一种新的,直接add(i,a[i]),(s[i]为a[1]到a[i]的和)
2、前缀和思想,树状数组的Sum本身就是基于前缀和的思想。本题把比某数小的数的个数,通过开大量空间+后缀数组,高效的统计出来比某数小的数的个数
3、事实上我认为通过这个题。能够做出来一种O(nlogn)的排序算法。当然不完好的地方就是仅仅能是整数了,可是应该能够用vector+map解决?
贴自己的代码先。,,由于后面的Lrj大牛的代码太简洁...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <functional> using namespace std; #define MAXN 20010
#define SIZE 100015 int a[MAXN],sma[SIZE],c[SIZE],s[SIZE],e[SIZE],tot[SIZE];
int n,mmax; int lowbit(int i)
{
return i & (-i);
} int sum(int i)
{
int ans=0;
for(;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
} void add(int x, int d) {
while(x <= SIZE) {
c[x] += d; x += lowbit(x);
}
} void Init()
{
memset(c,0,sizeof(c));
memset(a,0,sizeof(a));
memset(sma,0,sizeof(sma));
memset(s,0,sizeof(s));
memset(e,0,sizeof(e));
memset(tot,0,sizeof(tot));
} int main()
{
//freopen("la4329.txt","r",stdin);
int t;
long long ans; scanf("%d",&t); while(t--)
{
mmax=0;
ans=0;
Init(); scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
mmax=max(mmax,a[i]);
add(a[i],1);
//c[i]=sum(a[i]-1);
e[a[i]]=1;
sma[a[i]]=sum(a[i]-1); }
memset(c,0,sizeof(c));
for(int i=1;i<=mmax;i++)
{
s[i] =s[i-1]+e[i];
c[i]=s[i]-s[i-lowbit(i)];
tot[i]=sum(i-1);
}
///////////////////////
//for(int i=1;i<=n;i++)
//{
// printf("sma[a[%d]] = %d tot(%d) = %d\n",i,sma[a[i]],a[i],tot[a[i]]);
//}
///////////////////////
for(int i=1;i<=n;i++)
{
int tmp = tot[a[i]]-sma[a[i]];/*a[i]之后比a[i]小的个数*/
ans+=(long long )tmp*(i-1-sma[a[i]])+(long long)sma[a[i]]*(n-i-tmp);
} printf("%lld\n",ans);
} return 0;
}
标程
// LA4329 Ping pong
// Rujia Liu
#include<cstdio>
#include<vector>
using namespace std; //inline int lowbit(int x) { return x&(x^(x-1)); }
inline int lowbit(int x) { return x&-x; } struct FenwickTree {
int n;
vector<int> C; void resize(int n) { this->n = n; C.resize(n); }
void clear() { fill(C.begin(), C.end(), 0); } // ¼ÆËãA[1]+A[2]+...+A[x] (x<=n)
int sum(int x) {
int ret = 0;
while(x > 0) {
ret += C[x]; x -= lowbit(x);
}
return ret;
} // A[x] += d (1<=x<=n)
void add(int x, int d) {
while(x <= n) {
C[x] += d; x += lowbit(x);
}
}
}; const int maxn = 20000 + 5;
int n, a[maxn], c[maxn], d[maxn];
FenwickTree f; int main() {
freopen("la4329.txt","r",stdin);
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
int maxa = 0;
for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); maxa = max(maxa, a[i]); }
f.resize(maxa);
f.clear();
for(int i = 1; i <= n; i++) {
f.add(a[i], 1);
c[i] = f.sum(a[i]-1);
}
f.clear();
for(int i = n; i >= 1; i--) {
f.add(a[i], 1);
d[i] = f.sum(a[i]-1);
} long long ans = 0;
for(int i = 1; i <= n; i++)
ans += (long long)c[i]*(n-i-d[i]) + (long long)(i-c[i]-1)*d[i];
printf("%lld\n", ans);
}
return 0;
}
树状数组 LA 4329 亚洲赛北京赛区题的更多相关文章
- HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- POJ 2155 Matrix 【二维树状数组】(二维单点查询经典题)
<题目链接> 题目大意: 给出一个初始值全为0的矩阵,对其进行两个操作. 1.给出一个子矩阵的左上角和右上角坐标,这两个坐标所代表的矩阵内0变成1,1变成0. 2.查询某个坐标的点的值. ...
- 二维树状数组+差分【p4514】上帝造题的七分钟
Description "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n\times m\)矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为\((a,b)\),右 ...
- 树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)
前提是数的范围较小 1 数据范围:O(n) 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i) 3 添加:log(n) (树状数组) 4 删除:log(n) ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- poj 2155 Matrix---树状数组套树状数组
二维树状数组模版,唯一困难,看题!!(其实是我英语渣) Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22098 ...
- poj2155 树状数组 Matrix
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 14826 Accepted: 5583 Descripti ...
- Why Did the Cow Cross the Road III(树状数组)
Why Did the Cow Cross the Road III 时间限制: 1 Sec 内存限制: 128 MB提交: 65 解决: 28[提交][状态][讨论版] 题目描述 The lay ...
- [BZOJ4765]普通计算姬(分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 1725 Solved: 376[Submit][Status][Discus ...
随机推荐
- 【原】CentosDocker安装(一)
CentosDocker安装 来源:https://www.runoob.com/docker/centos-docker-install.html 1.前提条件 目前,CentOS 仅发行版本中的内 ...
- Python的前世今生
放弃 拾起 放弃 拾起 最终决定好好的编写一次Python的学习笔记 人生苦短,我用Python --------------Life is short, you need Python 再不抓紧,就 ...
- react-native Socket Event 在控制台的输出
在XCode中运行react-native 的时候,避免不了的要查看日志信息 ,但是react-native中的Socket的日志简直是太多了,往往是刚看到自己想要看到的信息的时候,瞬间就被最新的日志 ...
- cc.Label
cc.Label 1:cc.Label是显示文字的组件;2:cc.Label属性面板: String: 文本显示的内容; Horiznotal: 水平对齐的方式: 左 右 居中; Vertial ...
- kubernetes 知识点及常用命令
一.附上一个Deployment文件 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selec ...
- I - DFS(依然是漫水填充)
Description There is a rectangular room, covered with square tiles. Each tile is colored either red ...
- List<> 集合 删除指定行
不多说,直接上代码 public class Name { public string NameInfo { get; set; } } 删除值为Name2的行 static void Main(st ...
- Vue如何实现swiper左右滑动内容区控制导航tab同时切换高亮
Vue如何实现左右滑动内容区控制导航tab同时切换高亮,实现的效果是:点击导航按钮时内容区发生改变,左右滑动内容区时导航按钮跟随切换高亮,停留在某个内容区时刷新页面后仍然停留在当前内容区. ...
- 基本dos
文件夹的操作: 进入指定盘符:盘符名+: dir:列出当前控制台下的所有文件以及文件夹 . cd +文件夹名称:进入指定文件夹 cd.. 返回上一级 cd \返回到当前目录的根目 ...
- Qt项目——数字内容管理系统的参考资料和细节
打开文件路径,若带空格,要用引号括起路径 LPCWSTR与QString的转换:LPCWSTR strL = strQ.toStdWString().c_str(); 用指定程序打开文件(选择文件的打 ...