1. 程式人生 > >折半搜尋

折半搜尋

題目大意: 給你個質數集合S,S25|S|\le25,問有多少不超過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); }