ABC280D题解

修改日志

2022/12/20  9:222022/12/20\text{ }\text{ }9:22:修改了时间复杂度。

思路

核心算法:二分

一:分解质因数

首先,对输入的 KK,进行分解质因数,若分解后质数 pp 有 ll 个,则 sump=lsum_p=l。

质因数的枚举

显然不能暴力。

但是,对于一个正整数 KK,只要 pp 枚举到 K\sqrt{K} 即可,因为如果 p mod K=0(p>K)p\bmod K=0(p\gt \sqrt{K}),那么 K÷pK\div p 一定 <K\lt \sqrt{K},那这一定会在之前除掉了。

所以以只要在 [1,⌊K⌋][1,\lfloor\sqrt{K}\rfloor] 内枚举 pp 即可

对于每个 pp,做如下的事情:

while(K2%i==0) K2/=i,sum[i]++;

这里的 ii 就是 pp,K2K2 的初值是 KK(由于 KK 要做边界)。

最后,如果 K2>1K2\gt 1,则输出 K2K2,结束程序。(因为这个 K2K2 一定是质数)

分解质因数代码:

long long K2=k;
for(long long i=2;i<=sqrt(k)+100;i++){
	while(K2%i==0) K2/=i,sum[i]++;
}
if(K2!=1) return !printf("%lld\n",K2);

二:二分答案

Q:为什么能用二分?
A:因为答案满足单调性。
Q:具体点?
A:你自己往下看吧!

因为如果一个正整数 aa 满足 aa 的阶乘是 KK 的倍数,那么 a+ba+b 的阶乘一定也是 KK 的倍数,满足单调性,可以二分。


定义左边界为 ll,右边界为 rr,初值:l=1,r=K+100l=1,r=K+100(稍微大一点,其实没必要,因为 KK 的阶乘一定是 KK 的倍数)。

对于每个 midmid,用 一 的分解质因数的方法输出数组 sum2sum2,在将 sum2isum2_i 和 sumisum_i 作比较,如果有任意一个 ii 使得 sumi>sum2isum_i\gt sum2_i,就将 l←midl\gets mid,否则将 r←midr\gets mid。

最后输出 rr 即可

时间复杂度:Θ(log⁡2K×K)\Theta(\log_2K\times\sqrt{K})

代码(语言:c++,仅供参考,不可抄袭)

#include<bits/stdc++.h>
using namespace std;
long long k,sum[1001000],l=1,r;
int main(){
	scanf("%lld",&k);
	long long K2=k;
	for(long long i=2;i<=sqrt(k)+100;i++){
		while(K2%i==0) K2/=i,sum[i]++;
	}
	if(K2!=1) return !printf("%lld\n",K2);
	r=k+100;
	while(l<r-1){
		long long mid=l+r>>1,now=mid;
		bool f=0;
		for(long long i=2;i<=sqrt(k)+100;i++){
			long long p=i,s=0;
			while(p<=mid){
				s+=mid/p;
				p*=i;
			}
			if(sum[i]>s){
				f=1;
				break;
			}
		}
		if(f) l=mid;
		else r=mid;
	}
	return !printf("%lld",r);
}
posted @ 2022-12-19 22:15  fengxiaoyi  阅读(36)  评论(0)    收藏  举报  来源