BZOJ1053 [HAOI2007]反素数ant
题解已经烂大街了,lyd书上给的证明也很详细。
个人觉得lyd书上讲的引理2,3顺序应当反过来讲更符合正常思维。
讲一讲思维方式,反思一下为什么我没想到,以及是怎么才能往这方面想的。
首先数论题重要的还是要推性质。
根据定义,最先映在脑海里的应当是答案的转化,这个都可以想到。
然后是必要性推导:
反素数分解的质因子一定是从2开始连续的、幂次下降的,否则可以交换幂次等找到更小的、相同约数的数符合要求。
于是这就是反素数的一个性质,也是一个必要条件。
意思是说,我搜索形如这种式子的数,这个数不一定是反素数,但不满足这个形式的肯定不是反素数。
所以反素数一定可以被我搜到,而这种形式的、却并不是反素数的数不影响答案——与他们约数的个数相同的数中,
总会搜到反素数,可以来更新此最小值。
然后再想到这个质因子最多到23,共9个数,然后才想到搜索解决。
总结一下,思维过程是发掘性质(什么样的数可能是反素数)———从性质入手尝试寻找这种数。
其实我也没做出来。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define dbg(x) cerr << #x << " = " << x <<endl 7 using namespace std; 8 typedef long long ll; 9 typedef double db; 10 typedef pair<int,int> pii; 11 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 12 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 16 template<typename T>inline T read(T&x){ 17 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 18 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 19 } 20 const int N=2000+7,INF=0x7f7f7f7f; 21 const int a[13]={0,2,3,5,7,11,13,17,19,23}; 22 int num[N]; 23 int n,ans; 24 void dfs(int k,int s,int tot,int las){ 25 MIN(num[tot],s); 26 if(k>9)return; 27 for(register int i=1,res=a[k];i<=las&&s*1ll*res<=n;++i,res*=a[k]){ 28 dfs(k+1,s*res,tot*(i+1),i); 29 } 30 } 31 32 int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout); 33 read(n);memset(num,0x7f,sizeof num); 34 dfs(1,1,1,30); 35 for(register int i=1;i<=2000;++i)if(num[i]!=INF)ans=num[i]; 36 return printf("%d\n",ans),0; 37 }