zoukankan      html  css  js  c++  java
  • [51nod1533] 一堆的堆

    问题描述

    现在有一个长度为n的数组 a1, a2, ..., an 。然后对于k从1到 n-1分别对该数组建k叉堆。现在要统计对于每一个k叉堆,里面有多少结点是不满足最小堆的性质的。即值比父亲的要小的结点有多少个。

    k叉堆的定义是这样的:数组的下标从1到n编号,对于某一个编号为v的结点,他的k个儿子编号是 k(v − 1) + 2, ..., kv + 1 (如果其中某些编号超出n,那些编号就不要)。在k叉堆中,除了根以外,每一个结点都有一个父亲。p(v)表示结点v的父亲。那么一个非根结点不满足最小堆性质当且仅当 av < ap(v) 。

    输入格式

    单组测试数据。
    第一行有一个整数 n (2≤n≤2*10^5)。
    第二行有n个用空格分开的整数a1, ..., an (-109≤ai≤109)。

    输出格式

    输出n-1个数字,第k个数字代表k叉堆中不满足最小堆性质的结点数目 (k=1, 2, ..., n-1)。

    样例输入

    5
    1 5 4 3 2

    样例输出

    3 2 1 0

    解析

    一个节点不合法当且仅当它的儿子节点中存在比它小的值。观察发现,一个节点在 (k) 确定时,它的儿子区间是可以直接算出来的。我们不妨按权值从小到大依次加入点,对每一个点枚举 (k) ,判断对应的儿子区间里是否有比他小的值。这个用树状数组就可以高效的实现。

    对于每一个点,当 (k) 大于一定值的时候整个儿子区间就会到 (n) 外面去。所以枚举 (k)(O(nlog n)) 的。

    代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define N 300002
    using namespace std;
    struct node{
    	int v,p;
    }a[N];
    int n,i,j,k,c[N],ans[N];
    int read()
    {
    	char c=getchar();
    	int w=0,f=1;
    	while(c<'0'||c>'9'){
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w*f;
    }
    int lowbit(int x)
    {
    	return x&(-x);
    }
    int ask(int x)
    {
    	int ans=0;
    	for(int i=x;i>=1;i-=lowbit(i)) ans+=c[i];
    	return ans;
    }
    void add(int x,int y)
    {
    	for(int i=x;i<=n;i+=lowbit(i)) c[i]+=y;
    }
    int my_comp(const node &a,const node &b)
    {
    	return a.v<b.v;
    }
    int main()
    {
    	n=read();
    	for(i=1;i<=n;i++) a[i].v=read(),a[i].p=i;
    	sort(a+1,a+n+1,my_comp);
    	for(i=k=1;i<=n;i++){
    		int pos=a[i].p+1;
    		for(j=1;j<n;j++){
    			if(pos>n){
    				if(pos-j+1<=n) ans[j]+=ask(n)-ask(pos-j);
    				else break;
    			}
    			else ans[j]+=ask(pos)-ask(pos-j);
    			pos+=a[i].p;
    		}
    		if(a[i+1].v!=a[i].v){
    			while(k<=i) add(a[k].p,1),k++;
    		}
    	}
    	for(i=1;i<n;i++) printf("%d ",ans[i]);
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    How do you Design a Circular FIFO Buffer (Queue) in C?

    搞懂分布式技术5:Zookeeper的配置与集群管理实战
    Spring boot 启动提示数据源错误
    IntelliJ IDEA 如何配置数据源
    Windows 10 中你可能用得最多的快捷键
    JUnit 5 测试问题 throws java.lang.Exception’ must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS)
    Intellij IDEA 如何自动生成 serialVersionUID
    Docsify 初始化文件夹
    Docsify 安装
  • 原文地址:https://www.cnblogs.com/LSlzf/p/13696175.html
Copyright © 2011-2022 走看看