洛谷P1463题解

题目链接:https://www.luogu.com.cn/problem/P1463

首先,一看到题,就知道是道数论题,先口胡一个平方暴力,由于是道省选题,肯定过不了。

打表?估计要跑个十几年。。

先假设x的一个约数为a,a肯定小于等于根号下x,因为这样可以求出另一个约数x/a,再特判一下x是平方数的情况,于是我们两重循环,每重循环根号下x,时间复杂度O(n)。

正当思考是否准确时,一看数据范围,2e9,当场吐血。

O(logn)算法?快速幂?二分?你逗我?

O(1)算法?显然,这道题是求一个区间(1~n)中符合条件的最大值,没法加加减减得出答案。

显然,这题时间复杂度和n没有关系。

思考一个数的约数是怎么得来的。

设这个数为x,则x=p1^k1*p2^k2*...*pn^kn,约数个数为(k1+1)*(k2+1)*...*(kn+1),证明么,乘法原理,分步相乘。

这里的p数列都为素数且单调上升。

要让k数列尽可能的大,就要让p数列尽可能小,我们可以大胆猜想:p数列只取素数的前几项,至于前几项,实践出真知= =

然后呢?枚举k数列。。(其实这是一道搜索题,并不是数论题

好吧,放上代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int sum[20]={0,2,3,5,7,11,13,17,19,23,29,31,33};//素数表
 4 long long n,ans,qwq;
 5 void dfs(long long x,long long y,long long z){//x表示sum数组下标,y是当前数字,z是约数个数
 6     if(z>qwq){
 7         qwq=z;
 8         ans=y;
 9     }
10     if(z==qwq&&ans>y)ans=y;
11     if(x>11)return;
12     for(long long i=1;i<=n;++i){
13         if(y*sum[x]>n)return;
14         dfs(x+1,y*sum[x],z*(i+1));
15         y*=sum[x];
16     }
17 }
18 signed main(){
19     cin>>n;
20     dfs(1,1,1);
21     cout<<ans<<endl;
22     return 0;
23 }

这种题刚上手肯定会一脸懵,做了一定的题之后肯定会有所进步。

码字不易,点个赞吧QwQ

猜你喜欢

转载自www.cnblogs.com/-YueYang-/p/12625810.html