好数 - 折半搜索

题目大意:
给你个质数集合S, ∣ S ∣ ≤ 25 |S|\le25 S25,问有多少不超过n的数字其质因数分解的质因子都在S中。
题解:
直接折半爆搜即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
const int K=28,N=10000000;lint n,lst1[N],lst2[N],ans,ans2;int p[K],p1[K],p2[K];
inline int dfs(int *p,int x,int c,lint v,lint *lst,int &lc)
{
    if(x==c+1) return lst[++lc]=v,0;
    lint w=n/v;dfs(p,x+1,c,v,lst,lc);
    while(w>=p[x]) w/=p[x],dfs(p,x+1,c,v*=p[x],lst,lc);
    return 0;
}
inline int solve(int *p,int c,lint *lst,int &lc)
{   return lc=0,dfs(p,1,c,1,lst,lc),sort(lst+1,lst+lc+1),0; }
int main()
{
    int k,c1=0,c2=0,lc1,lc2;scanf("%d%lld",&k,&n);
    rep(i,1,k) scanf("%d",&p[i]);sort(p+1,p+k+1);
    int t=5;
    if(k<=2*t)
    {
        rep(i,1,t) p1[++c1]=p[i];
        rep(i,t+1,k) p2[++c2]=p[i];
    }
    else{
        rep(i,1,t) p1[++c1]=p[i],p1[++c1]=p[k-i+1];
        rep(i,t+1,k-t) p2[++c2]=p[i];sort(p1+1,p1+c1+1);
    }
    solve(p1,c1,lst1,lc1),solve(p2,c2,lst2,lc2);
    for(int i=1,j=lc2;i<=lc1;ans+=j,(j?ans2=max(ans2,lst1[i]*lst2[j]):0),i++)
        while(j&&!(lst1[i]<=n/lst2[j])) j--;
    return !printf("%lld\n%lld\n",ans2,ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值