传送门:bzoj1053
题解
打表是不可能的(这辈子都不可能的)。
搜索是必须的。考虑如何高效地剪枝。
设 x = ∏ i = 1 n p i k i ( p i ∈ P ) x=\prod \limits_{i=1}^n p_i^{k_i}(p_i\in P) x=i=1∏npiki(pi∈P),则 g ( x ) = ∏ i = 1 n ( k i + 1 ) g(x)=\prod \limits_{i=1}^n(k_i+1) g(x)=i=1∏n(ki+1)。
当存在 p i < p j p_i<p_j pi<pj且 k i < k j k_i<k_j ki<kj时, x x x必然不是反素数,因为 s w a p ( k i , k j ) swap(k_i,k_j) swap(ki,kj)后能得到一个更小的 g ( x ′ ) g(x') g(x′)满足 g ( x ′ ) = g ( x ) g(x')=g(x) g(x′)=g(x)。
所以反素数必然是由最小的前几个质数构成的,且次幂单调不增。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,ans=0;ll cur;
int p[20]={2,3,5,7,11,13,17,19,23,29,31,37,41};
void dfs(ll v,int pos,ll val,int lim)
{
if(pos==10){
if(val>=cur){
if(val>cur) cur=val,ans=v;
else if(v<ans) ans=v;
}
return;
}
for(int i=0;i<=lim;++i){
dfs(v,pos+1,val*(i+1),i);
v*=p[pos];if(v>n) break;
}
}
int main(){
scanf("%d",&n);
dfs(1,0,1,31);
printf("%d",ans);
return 0;
}