ABC-280解题报告
D. Factorial and Multiple
题意:给你一个
,求最小的 使得 。 。
做法一
考虑将
检查
勒让德定理有一个扩展形式,描述为:
By cxm1024
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
int k,ans=0;
cin>>k;
for(int i=2;i*i<=k;i++) {
if(k%i!=0) continue;
int cnt=0,l=1,r=k;
while(k%i==0) cnt++,k/=i;
while(l<r) {
int mid=(l+r)/2,now=0;
for(int x=i;x<=mid;x*=i) {
now+=mid/x;
if(now>=cnt) break;
}
if(now>=cnt) r=mid;
else l=mid+1;
}
ans=max(ans,l);
}
if(k!=1) ans=max(ans,k);
cout<<ans<<endl;
return 0;
}
这个做法有许多本质相同的变种,如:每次将
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
rep(i,0,t) solve();
}
void solve(){
ll K;
cin>>K;
ll ans=0;
auto p=Prime_factorization(K);
for(auto x:p){
ll l=1,r=K;
while(r-l>1){
ll med=(r+l)/2;
ll D=med;
ll tmp=0;
while(med){
med/=x.first;
tmp+=med;
}
if(tmp<x.second) l=D;
else r=D;
}
chmax(ans,r);
}
cout<<ans<<"\n";
}
void solve(){
int k;cin>>k;
auto p = pollard_rho_fast::factorize2(k);
int lb=0, ub = 1e12+5;
while(ub-lb>1){
int mid=(lb+ub)/2;
for(auto x:p){
int num=x.a;
int cnt=x.b;
int t=0;
int now=mid;
while(now){
t += now / num;
now /= num;
}
if(t < cnt) goto fail;
}
ub=mid;continue;
fail:;lb=mid;
}
o(ub);
}
signed main(){
cin.tie(0);
ios::sync_with_stdio(0);
cout<<fixed<<setprecision(20);
int t; t = 1; //cin >> t;
while(t--) solve();
}
#include <stdio.h>
void chmax(long long* a, long long b)
{
if (*a < b) *a = b;
}
int main()
{
long long K;
scanf("%lld", &K);
int j;
long long i, ans = 1, tmp, tmpp;
for (i = 2; i * i <= K; i++) {
if (K % i != 0) continue;
for (j = 0; K % i == 0; j++, K /= i);
for (tmp = i; 1; tmp += i) {
for (tmpp = tmp / i, j--; tmpp % i == 0; tmpp /= i, j--);
if (j <= 0) break;
}
chmax(&ans, tmp);
}
if (K >= 2) chmax(&ans, K);
printf("%lld\n", ans);
fflush(stdout);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
map<long long,long long> mp;
long long k;
vector<long long> v;
long long ma;
void fjzys(long long a)
{
long long x=a;
for(long long t=2;t*t<=a;t++)
{
//cout<<t*t<<endl;
if(x%t==0)
v.push_back(t);
while(x%t==0)
{
mp[t]++;
x/=t;
//cout<<t<<" ";
}
}
if(x!=1)
{
v.push_back(x);
mp[x]++;
}
}
int main()
{
cin>>k;
fjzys(k);
for(long long t=0;t<v.size();t++)
{
long long sum=0;
for(long long i=1;;i++)
{
long long x=i;
long long b=0;
while(x%v[t]==0)
{
x/=v[t];
b++;
}
sum+=b+1;//提前跑了一层
if(sum>=mp[v[t]])
{
ma=max(i*v[t],ma);//补回来
break;
}
}
}
cout<<ma;
return 0;
}
做法二
考虑直接枚举
正确性证明:
假设
另一种证法:在
By noimi
int main() {
LL(k);
auto f = factor(k);
ll ma = 0;
rep(i, si(f)) { chmax(ma, f[i].fi); }
ll now = 1;
rep(i, 1, ten(8)) {
now = now * i % k;
if(!now) {
OUT(i);
exit(0);
}
}
OUT(ma);
}
还有一种不同的实现,每次枚举到一个数时将它能覆盖到的
By physharp
k=int(input())
import math
for n in range(1,2000001):
k//=math.gcd(k,n)
if k<2: exit(print(n))
print(k)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步