[Jzoj] 3020. 最多的约数

本文介绍了一种寻找在给定范围内具有最多约数的整数的方法,并通过质因数分解来优化搜索过程,确保找到最小的符合条件的数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

给定一个正整数NNN,对于所有不超过NNN的正整数,找到包含约数最多的一个数。如果有多个这样的数,那么回答最小的那个

题目解析

先给出一个定义:

WWW的质因数分解为:
W=p1W=p_1W=p1a1∗p2*p_2p2a2 ∗…∗pm*…*p_mpmam(p1…pm为素数,a1…am≥1)(p_1…p_m为素数,a_1…a_m≥1)(p1pma1am1)
WWW(a1+1)(a2+1)…(am+1)(a_1+1)(a_2+1)…(a_m+1)(a1+1)(a2+1)(am+1)个约数

所以,可以枚举因数中包含000222111222……kkk222,直至m∗2km∗2^km2k大于区间的上限NNN

在这个基础上枚举3、5、7……3、5、7……357的情况,算出现在已经得到的mmm的约数个数,
同时与原有的记录进行比较和替换。直至所有的情况都被判定过了

接着,给出如下例子:

12=22∗312=2^2∗312=223
18=32∗218=3^2*218=322

121212181818的质因数分解““模式””完全相同,所以它们的约数个数是相同的

但是由于121212的质因数分解中222的指数大于333的指数,181818的质因数分解中333的指数大于222的指数,所以12&lt;1812&lt;1812<18

所以,可以在枚举时进行一个优化,使得枚举到的数字中222的指数不小于333的指数,333的指数不小于555的指数…………这样我们就能够得到质因数分解““模式””相同的最小数

代码

#include<bits/stdc++.h>
#define L long long
using namespace std;
L n,pi,ans,num;
int p[10005];
bool flag[1000010];
void fun()
{
	for(int i=2;i<=1000000;i++)
	 if(!flag[i])
	 {
	   p[++pi]=i;
	   for(int j=2;j<=1000000/i;j++)
	    flag[j*i]=1;
	 }
}
void dfs(L x,int lev,int t,int s)
{
	if(t>num||(t==num&&x<ans)) ans=x,num=t;
	int j=0,l=1,q;
	L i=x;
	while(j<s)
	{
	  j++,l++;
	  if(n/i<p[lev]) break;
	  q=t*l;
	  i*=p[lev];
	  if(i<=n) dfs(i,lev+1,q,j);
	}
}
int main()
{
	fun();
	cin>>n;
	dfs(1,1,1,30);
	cout<<ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值