• BZOJ 4524(贪心+二叉堆)


    题面

    若一个大于 11 的整数M分解质因数后到的有重复的质因数序列有k 项,其最大的质因子为 (a_k),并且满足 ({a_k}^k leq N,k<128),我们就称整数 M 为 N-伪光滑数。

    现在给出 N*N,求所有整数中,第 K大的 N-伪光滑数。

    分析

    先筛出128以内的所有质数

    根据题意贪心考虑,显然M的质因数分解中最大的质数越大越好

    于是我们把每个质数p的1次方,2次方,3次方...k次方((p^k leq n))加入堆(堆顶元素最大).

    然后取k-1次,每次对于取出来的数x,除掉它的最大质因子,乘上一个次大的质因子,这样就构造出了一个更小的数,且它显然是 N-伪光滑数

    取完k-1次后的堆顶就是最大的质数了

    用优先队列模拟这个过程,由于优先队列中的元素可能会重复,会影响结果(重复的数被取出多次,导致取出来的不是第k大的),我们只要一次取出所有的最大元素即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<set>
    #include<queue>
    #define maxn 1005
    using namespace std;
    long long n;
    int k;
    
    int cnt=0;
    int vis[maxn];
    int prime[maxn];
    void sieve(int n){
    	for(int i=2;i<=n;i++){
    		if(!vis[i]){
    			prime[++cnt]=i;
    		}
    		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0) break;
    		}
    	}
    }
    
    priority_queue<long long>q;
    int main(){
    	scanf("%lld %d",&n,&k);
    	sieve(128);
    	for(int i=1;i<=cnt;i++){
    		for(long long x=prime[i];x<=n;x*=prime[i]){
    			q.push(x);
    		}
    	}
    	for(int i=1;i<=k-1;i++){
    		long long x=q.top();
    		while(!q.empty()&&x==q.top()) q.pop();
    		long long y;
    		for(int i=1;i<=cnt;i++){
    			if(x%prime[i]==0){
    				y=x/prime[i]*prime[i-1];
    				q.push(y);
    			}
    		}
    	}
    	printf("%lld
    ",q.top());
    }
    
  • 相关阅读:
    高德地图API之公交路线
    高德地图API之骑行路线
    高德地图API之货车路线
    高德地图API之步行路线
    高德地图API之驾车路线
    高德地图API常用控件的添加与删除(鹰眼、工具条、比例尺)
    高德地图API,地图类型切换(卫星地图)
    高德地图API之缩放比例尺控件+3D转换
    Laravel 虚拟开发环境 Homestead 密码
    优化mysql
  • 原文地址:https://www.cnblogs.com/birchtree/p/10568060.html
Copyright © 2020-2023  润新知