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的数取 ...
随机推荐
- DSL 系列(2) - 插件的论述与实现
前言 本文主要探讨基于 DSL(domain specific language) 之上的插件设计,他们是领域的附属,为领域提供额外的服务,但领域不依赖于他们. 1. 论述 领域应当尽可能地去专注他的 ...
- flask 单元测试
程序开发过程中,代码是为了完成需求,当代码编译通过后,能不能保证功能的正常实现,需要我们编写测试代码,模拟程序运行过程,检验功能是否符合预期. 单元测试主要面向一些功能单一的模块进行. 单元测试,实际 ...
- tornado设置cookie并加密
最近看看tornado,遇到了sso的东西,了解下如何设置cookie 1.基本cookie set_cookie 方法在用户的浏览中设置 cookie: get_cookie 方法在用户的浏览中获取 ...
- Day2 Numerical simulation of optical wave propagation之标量衍射理论基本原理(二)
2.麦克斯韦方程组的简单行波解 讨论通过线性.各向同性.均匀.无色散.无限电荷和电流的电介质材料的光波传输.在这种情况下,介质具有如下属性: (1)推导获得波动方程( 由麦克斯韦方程组导出的.描述电磁 ...
- Day2 Python基础之基本操作(一)
1.常用命令 调用cmd窗口 Win+R cmd命令窗口清屏 cls cmd命令窗口在运行python时清屏 import os i=os.system('cls') cmd命令窗口在运行python ...
- java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader
我的解决办法: 1.如果是application工程,则在程序中打印出 system.out.println(System.getProperty("java.endo ...
- Linux kernel support docker storage driver aufs
How to make docker use aufs in CentOS 7? - Server Faulthttps://serverfault.com/questions/650208/how- ...
- asp.net Json序列化
Json作为一种数据传输格式与标准被广泛的使用在项目开发中,可以说简直离不开它.那么怎么来生成JSON格式的数据就成了我们首先需要解决的问题这里我们使用.net. 首先是获取数据 public ban ...
- Oracle RMAN备份与还原
RMAN在数据库服务器的帮助下实现数据库文件.控制文件.数据库文件与控制文件的映像副本.归档日志文件.数据库服务器参数文件的备份. RMAN的特点: (1) 支持增量备份:传统的exp与expdp备份 ...
- Struts2——namespace、action、以及path问题
简单的介绍下Struts2中的几个简单的问题(namespace.action.以及path问题) namespace(命名空间) Namespace决定了action的访问路径,默认为“”,意味着可 ...