Codeforces300 F. A Heap of Heaps
出处: Codeforces
主要算法:树状数组/线段树
难度:4.6
思路分析:
在没看到数据范围之前真是喜出望外,直到发现O(n^2)会被卡……
其实也不是特别难的
我们要做的事情就是对于每一个节点v,求出当k分别取\(1,2,3,...,n\)时比v的权值小的v的儿子数量。既然要求每个节点的,那n自然是要扫的。那有没有能够在O(log n)复杂度内求出权值小于v的节点数量的方法呢?这自然让我们联想到了O(log n)的数据结构——树状数组或者线段树。
数组a[i]保存节点的信息。a[i].x表示权值,a[i].idx表示编号(位置)。首先将数组a按照x从小到大进行排序,并在处理好每一个节点后用树状数组更新bit[a[i].idx],让它+1。bit[i]维护的其实就是位置i是否被更新过。那么设想一下,因为a数组是按照权值进行排序的,所以已经被更新过的点的权值一定<=a[i]。因此我们可以查询区间[left,right](表示节点v的子节点的位置的左右位置的最值),得到的答案就是小于节点v权值的子节点的数量。而由于此序列是一定的,无论k怎么变,只需要改变一下left和right就可以得到不同的堆的答案了。所以我们进行如下操作:
\(ans[k] += Query(right) - Query(left-1);\)
我想意义已经很清楚了。
最后有一个复杂度的计算问题:我在外层扫描了节点i,内层扫描了堆的叉数k,又做了bit,为什么复杂度会是\(O(n log n)\)?不应该是\(O(n^2 log n)\)吗?但是总共就n个节点,并且k越大叶子就越多,所以到后来几乎一进循环就会跳出。所以复杂度就等同于\(O(n)\)了
代码注意点:
排序改成双关键字。因为要先更新父亲,再更新儿子。不然与父亲节点权值相同的儿子会被算为违反的。
Code
/*By QiXingzhi*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int N = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) +(x << ) + c - '', c = getchar();
return x * w;
}
struct Number{
int x,idx;
}a[N];
int n,m,left,right;
int bit[N],ans[N];
inline bool comp(Number& a, Number& b){
if(a.x == b.x) return a.idx < b.idx;
return a.x < b.x;
}
inline int GetLeft(int v, int k){
return (k * (v-) + );
}
inline int GetRight(int v, int k){
return ((k * v) + );
}
inline int Query(int x){
int i = x;
int res = ;
while(i > ){
res += bit[i];
i -= i & (-i);
}
return res;
}
inline void Update(int x, int k){
int i = x;
while(i <= N){
bit[i] += k;
i += i & (-i);
}
}
int main(){
n = r;
for(int i = ; i <= n; ++i){
a[i].x = r;
a[i].idx = i;
}
sort(a+,a+n+,comp);
for(int i = ; i <= n; ++i){
for(int k = ; k < n; ++k){
left = GetLeft(a[i].idx,k);
right = GetRight(a[i].idx,k);
if(left > n) break;
if(right > n) right = n;
ans[k] += Query(right) - Query(left-);
}
Update(a[i].idx, );
}
for(int i = ; i < n; ++i){
printf("%d ", ans[i]);
}
return ;
}
Codeforces300 F. A Heap of Heaps的更多相关文章
- Codeforces Round #300 F - A Heap of Heaps (树状数组 OR 差分)
F. A Heap of Heaps time limit per test 3 seconds memory limit per test 512 megabytes input standard ...
- Codeforces 538 F. A Heap of Heaps
\(>Codeforces \space 538 F. A Heap of Heaps<\) 题目大意 :给出 \(n\) 个点,编号为 \(1 - n\) ,每个点有点权,将这些点构建成 ...
- [codeforces538F]A Heap of Heaps
[codeforces538F]A Heap of Heaps 试题描述 Andrew skipped lessons on the subject 'Algorithms and Data Stru ...
- L - A Heap of Heaps CodeForces - 538F 主席树
L - A Heap of Heaps CodeForces - 538F 这个是一个还比较裸的静态主席树. 这个题目的意思是把这个数组变成k叉树,然后问构成的树的子树小于等于它的父节点的对数有多少. ...
- Codeforces538F A Heap of Heaps(函数式线段树)
题意:给你一个数组a[n],对于数组每次建立一个完全k叉树,对于每个节点,如果父节点的值比这个节点的值大,那么就是一个违规点,统计出1~n-1完全叉树下的违规点的各自的个数. 一个直觉的思想就是暴力, ...
- CodeForces 538F A Heap of Heaps
题意 给定一个长度为n的数组A,将它变为一颗k叉树(1 <= k <= n - 1)(堆的形式编号). 问对于每一个k,有多少个节点小于它的父节点. 解题 显然,最初的想法是暴力.因为树的 ...
- [CF538F]A Heap of Heaps(主席树)
题面 题意:给你一个数组a[n],对于数组每次建立一个完全k叉树,对于每个节点,如果父节点的值比这个节点的值大,那么就是一个违规点,统计出1~n-1完全叉树下的违规点的各自的个数. 分析 注意到完全k ...
- Codeforces Round #300 解题报告
呜呜周日的时候手感一直很好 代码一般都是一遍过编译一遍过样例 做CF的时候前三题也都是一遍过Pretest没想着去检查... 期间姐姐提醒说有Announcement也自信不去看 呜呜然后就FST了 ...
- CF数据结构练习
1. CF 438D The Child and Sequence 大意: n元素序列, m个操作: 1,询问区间和. 2,区间对m取模. 3,单点修改 维护最大值, 取模时暴力对所有>m的数取 ...
随机推荐
- NanoFabric-ServiceFabric 操作手册
service-fabric-52abp-ocelot A Service Fabric sample with a Frontend, one API Gateway and 52abp Micro ...
- C++与Java,C#的异同(一):值,地址,引用
Java,C#已经比较熟悉,最近在从0开始自学C++.学习过程中必然会与Java,C#进行对比,有吐槽,也有点赞. 先来讲讲最基本也是最重要的部分:参数传递的方式. 对于类型, Java分基本类型.复 ...
- Selenium库
'''自动化测试工具,支持多种浏览器.爬虫中主要用来解决JavaScrip渲染的问题.''''''基本使用'''from selenium import webdriverfrom selenium. ...
- PT与PX区别
字体大小的设置单位,常用的有2种:px.pt.这两个有什么区别呢? 先搞清基本概念:px就是表示pixel,像素,是屏幕上显示数据的最基本的点: pt就是point,是印刷行业常用单位,等于1/72英 ...
- YCSB报": No such file or directory"异常
异常信息如下: 文件路径.权限都没有问题. 上网遍寻无果,安装流程与官网一致,开始怀疑是环境问题,后来用别人能用的YCSB复制到本地,却能正常运行. 后来修改了ycsb文件,加了个空格,保存退出,再运 ...
- semantic-ui 标题
在semantic-ui中定义了5中标题样式,注意HTML中有h1-h6,而semantic-ui中只有h1-h5. 不过需要注意的是,semantic-ui的标题仍旧使用h1-h5来表示,但是在cl ...
- Jeecg-Boot Spring Boot
Jeecg-Boot 1.0 发布,企业级快速开发平台 - 开源中国https://www.oschina.net/news/104889/jeecg-boot-1-0-released
- ShowDoc上手
ShowDoc是什么 每当接手一个他人开发好的模块或者项目,看着那些没有写注释的代码,我们都无比抓狂.文档呢?!文档呢?!Show me the doc !! 程序员都很希望别人能写技术文档,而自己却 ...
- js压箱底的宝贝
框架的确好用, 不过他们也隐藏了JavaScript中丑陋的细节和DOM的运作机制. 如果你的目标是敢于自称"我懂JavaScript", 那么花时间学习框架无异于南辕北辙. 下面 ...
- AngularJS基于模块化的MVC实现
AngularJS基于模块化的MVC实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&qu ...