题目大意:
给你个质数集合S,
∣
S
∣
≤
25
|S|\le25
∣S∣≤25,问有多少不超过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);
}