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 }
View Code
posted @ 2019-09-05 17:38  Ametsuji_akiya  阅读(150)  评论(0编辑  收藏  举报