其他分享
首页 > 其他分享> > CodeForces - 538F--A Heap of Heaps(树状数组+离线)

CodeForces - 538F--A Heap of Heaps(树状数组+离线)

作者:互联网

题目链接https://codeforces.com/problemset/problem/538/F
Time limit 3000 ms Memory limit 524288 kB

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·10^5).

The second line contains n space-separated integers a1, …, an ( - 10^9 ≤ ai ≤ 10 ^ 9).

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.

Examples

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

Note

Pictures with the heaps for the first sample are given below; elements for which the property of the heap is violated are marked with red.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
In the second sample all elements are equal, so the property holds for all pairs.


题目大意:给你树上每个节点的值,问你当这棵树是k叉数的时候有多少不合法的元素,k=(1~n-1),不合法的元素定义为该节点的值小于父节点的值的元素。看note的图就应该可以理解了。

事实上这题的解法看起来有点暴力。。。但最后它只跑了150ms不到。。。

如果一个数对答案有贡献的话,那么也就代表id在它前面的有数大于它,至于他是谁的儿子就不是现在关心的了,所以我们可以先将他按照值排序,接下来按照id一个个插入树状数组中。然后查询的时候直接按照区间查询从左儿子到右儿子查询就好了:

for (int k=1; k<=n-1 && k*(id-1)+2<=n; k++){//暴力枚举k堆
    ans[k]+=query(min(n,k*id+1))-query(k*(id-1)+1);//左儿子到右儿子中比它小的数的数量.
}

算算复杂度,实际上约到后面复杂度越小,外面是for 到n,这里枚举的复杂度随着id的变大逐渐变小,其复杂的约为logn,所以最后的总复杂度是O(nlog2n)。

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;

const int mac=2e5+10;

struct node
{
    int val,id;
    bool operator <(const node &a)const {
        return val<a.val;
    }
}a[mac];

int ans[mac],tree[mac],n;

int lowbit(int x){return x&-x;}

void update(int pos,int val)
{
    for (int i=pos; i<=n; i+=lowbit(i)) tree[i]+=val;
}

int query(int pos)
{
    int sum=0;
    for (int i=pos; i; i-=lowbit(i)) sum+=tree[i];
    return sum;
}

void in(int &x)
{
    int f=0,mark=1;
    char ch=getchar();
    while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    if (ch=='-') mark=-1,ch=getchar();
    while (ch>='0' && ch<='9') f=(f<<3)+(f<<1)+ch-'0',ch=getchar();
    x=f*mark;
}

int main()
{
    in(n);
    for (int i=1; i<=n; i++)
        in(a[i].val),a[i].id=i;
    sort(a+1,a+1+n);
    for (int i=1; i<=n; i++){
        int p=i;
        while (a[i].val==a[p].val && p<=n) p++;
        for (int j=i; j<p; j++){
            int id=a[j].id;
            for (int k=1; k<=n-1 && k*(id-1)+2<=n; k++){
                ans[k]+=query(min(n,k*id+1))-query(k*(id-1)+1);
            }
        }
        for (int j=i; j<p; j++)
            update(a[j].id,1);
        i=p-1;
    }
    for (int i=1; i<n; i++)
        printf ("%d%c",ans[i],i==(n-1)?'\n':' ');
    return 0;
}

标签:Heaps,elements,Heap,离线,element,ch,heap,array,property
来源: https://blog.51cto.com/u_15249461/2870377