zoukankan      html  css  js  c++  java
  • CF912E Prime Gift

    题目大意

    给定一个大小为 n 的素数集合
    求出分解后只含这些质数因子的第 k 小整数
    题目链接

    题解

    在n这么小的情况下,肯定优先考虑暴搜
    可是爆搜显然空间开不下,
    那我们想想来如何优化这个暴搜,meet-in-the-middle!!!
    把整个素数集合分成两半,分别记录下每一部分元素可以组合出的所有小于 1E18 的数
    然后再二分答案,每次check过程中合并这两个集合中的元素,找到比 mid 小的个数就行了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    #define int long long
    #define in inline
    #define get getchar()
    #define pb push_back
    in int read()
    {
    	int t=0; char ch=get;
    	while( ch<'0' || ch>'9') ch=get;
    	while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
    	return t;
    }
    const int maxn=1e18;
    const int _=1e3+5;
    vector<int> v[3];
    int n,p[_],sums=0;
    in void dfs(int k,int i,int mul)
    {
    	if(i>n)
    	{
    		v[k].pb(mul);
    		return ;
    	}
    	for(re int qwe=1;;qwe*=p[i])
    	{
    		dfs(k,i+2,mul*qwe);
    		if(mul*qwe>maxn/p[i])return;
    	}
    }
    
    signed main()
    {
    	n=read();
    	v[1].pb(0),	v[2].pb(0);
    	for(re int i=1;i<=n;i++)
    		p[i]=read();
    	int k=read();
    	dfs(1,1,1);dfs(2,2,1);
    	sort(&v[1][1],&v[1][v[1].size()]);
    	sort(&v[2][1],&v[2][v[2].size()]);
    	int l=0,r=maxn,ans=0,len1=v[1].size()-1,len2=v[2].size()-1;
    	while(l<=r)
    	{
    		int mid=l+r>>1,res=0;
    		for(re int i=1,j=len2;j>=1&&i<=len1;res+=j,i++){
    			while(j&&v[2][j]>mid/v[1][i]) j--;
    		}
    		if(res<k) l=mid+1;
    		else r=mid-1,ans=mid;
    	}
    	cout<<ans<<endl;
    }
    
    
  • 相关阅读:
    Angular2新人常犯的5个错误
    好爱情,坏爱情
    关于css中a标签的样式
    移动端rem布局实践
    我们这一代人的困惑
    原创ui.router源码解析
    Web客户端数据存储学习笔记——Cookie
    喝汤了——如何用一年时间获得十年的能力和经验
    Petya勒索木马
    推荐几个精致的web UI框架
  • 原文地址:https://www.cnblogs.com/yzhx/p/11742257.html
Copyright © 2011-2022 走看看