博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #300 F - A Heap of Heaps (树状数组 OR 差分)
阅读量:5024 次
发布时间:2019-06-12

本文共 3767 字,大约阅读时间需要 12 分钟。

F. A Heap of Heaps
time limit per test
3 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

Andrew skipped lessons on the subject 'Algorithms and Data Structures' for the entire term. When he came to the final test, the teacher decided to give him a difficult task as a punishment.

The teacher gave Andrew an array of n numbers a1, ..., an. After that he asked Andrew for each k from 1 to n - 1 to build a k-ary heap on the array and count the number of elements for which the property of the minimum-rooted heap is violated, i.e. the value of an element is less than the value of its parent.

Andrew looked up on the Wikipedia that a k-ary heap is a rooted tree with vertices in elements of the array. If the elements of the array are indexed from 1 to n, then the children of element v are elements with indices k(v - 1) + 2, ..., kv + 1 (if some of these elements lie outside the borders of the array, the corresponding children are absent). In any k-ary heap every element except for the first one has exactly one parent; for the element 1 the parent is absent (this element is the root of the heap). Denote p(v) as the number of the parent of the element with the number v. Let's say that for a non-root element v the property of the heap is violated if av < ap(v).

Help Andrew cope with the task!

Input

The first line contains a single integer n (2 ≤ n ≤ 2·105).

The second line contains n space-separated integers a1, ..., an ( - 109 ≤ ai ≤ 109).

Output

in a single line print n - 1 integers, separate the consecutive numbers with a single space — the number of elements for which the property of the k-ary heap is violated, for k = 1, 2, ..., n - 1.

Sample test(s)
input
5 1 5 4 3 2
output
3 2 1 0
input
6 2 2 2 2 2 2
output
0 0 0 0 0 题意:给定一个序列,一次建立k叉堆(1 <= k <= n-1), 求n-1个堆中 不合法的点的个数。 按照题解:两种做法,,感觉还是第一种比较好,。 大致做法: 我们先把所有数字按照大小排序(记录他们在原始序列的位置), 然后对于 第i个数字, 假设它在原始数组中的位置为pos, 那么他的孩子的index是 k*(pos-1)+2 ~ k*pos+1, 我们按照从小到大加入到树状数组中, 那么对于这个数字 他的孩子中不合法的个数就是 query (min(k*pos+1, n)) - query(k*(pos-1)+2)。 然后做n次这样的操作就OK了。。
1 #include 
2 using namespace std; 3 const int MAXN = 2e5+10; 4 int arr[MAXN]; 5 int lowbit (int x) 6 { 7 return x & -x; 8 } 9 void modify(int x, int d) 10 { 11 while (x < MAXN) 12 { 13 arr[x] += d; 14 x += lowbit(x); 15 } 16 } 17 int query (int x) 18 { 19 int ans = 0; 20 while (x) 21 { 22 ans += arr[x]; 23 x -= lowbit(x); 24 } 25 return ans; 26 } 27 typedef pair
pii; 28 pii a[MAXN]; 29 int n, ans[MAXN]; 30 void solve () 31 { 32 memset(arr, 0, sizeof (arr)); 33 memset(ans, 0, sizeof (ans)); 34 for (int i = 1; i <= n; ) 35 { 36 int tmp = i; 37 while (tmp <= n && a[tmp].first == a[i].first) 38 tmp++; 39 for (int j = i; j < tmp; j++) 40 { 41 for (int k = 1; k <= n-1 && k*(a[j].second-1)+2 <= n; k++) 42 { 43 ans[k] += query(min(n, k*a[j].second+1)) - query(k*(a[j].second-1)+1); 44 } 45 } 46 for (int j = i; j < tmp; j++) 47 modify(a[j].second, 1); 48 i = tmp; 49 } 50 for (int i = 1; i <= n-1; i++) 51 { 52 printf("%d%c", ans[i], " \n"[i==n-1]); 53 } 54 } 55 int main(void) 56 { 57 #ifndef ONLINE_JUDGE 58 freopen("in.txt", "r", stdin); 59 #endif // ONLINE_JUDGE 60 while (~scanf ("%d", &n)) 61 { 62 for (int i = 0; i < n; i++) 63 { 64 scanf ("%d", &a[i+1].first); 65 a[i+1].second = i+1; 66 } 67 sort (a+1, a+n+1); 68 solve(); 69 } 70 return 0; 71 }

 

转载于:https://www.cnblogs.com/oneshot/p/4464437.html

你可能感兴趣的文章
T-SQL查询进阶--深入浅出视图
查看>>
MapKeyboard 键盘按键映射 机械革命S1 Pro-02
查看>>
Android读取url图片保存及文件读取
查看>>
完整ASP.Net Excel导入
查看>>
判断CPU大小端示例代码
查看>>
ARTS打卡第13周
查看>>
循环队列的运用---求K阶斐波那契序列
查看>>
pta 编程题14 Huffman Codes
查看>>
初始化bootstrap treeview树节点
查看>>
python selenium向<sapn>标签中写入内容
查看>>
JS常用坐标
查看>>
使用”结构化的思考方式“来编码和使用”流程化的思考方式“来编码,孰优孰劣?...
查看>>
C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)【转】...
查看>>
关于git的认证方式
查看>>
字符串按照字典序排列
查看>>
IOS 开发调用打电话,发短信
查看>>
CI 框架中的日志处理 以及 404异常处理
查看>>
keepalived介绍
查看>>
css3 标签 background-size
查看>>
python itertools
查看>>