Uva10791 Minimum Sum LCM
看同学的紫书(刘汝佳那本),还给人弄对了
真是衰呀。
昨天同学出来这么一道原题。
首先,对于质数,答案肯定是质数+1。这个可以miller-Rabin一波。
考虑合数,我们可以选择直接构造解。
如何构造?
首先这个肯定是质因数分解。然后在组合。如何组合?
首先我们很明白的算出来,在答案的可重集中。质因子不可能单独出现,或出现次数少于分解后他的幂。
如果此类情况发生,则lcm不为输入。
那么接下来就是考虑如何组合。
对于\(A>B\),有\(AB>B^2\)
所以肯定是这些质因子的幂的和。
所以答案就出来了
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
long long num[10]={0,2,3,5,7,11,13,17,19};
long long kasumi(long long a,long long b,long long p)
{
long long ans=1;
a=a%p;
while(b)
{
if(b&1)
ans=(ans*a)%p;
b>>=1;
a=(a*a)%p;
}
return ans;
}
bool test(long long val)
{
if(val==2)
return true;
if(val%2==0||val==1)
return false;
for(int i=1;i<=8;i++)
if(val==num[i])
return true;
long long t=0,tmp=val-1,now;
while((tmp&1)==0)
{
tmp>>=1;
t+=1;
}
for(int i=1;i<=8;i++)
{
now=kasumi(num[i],tmp,val);
long long nxt=now;
for(int i=1;i<=t;i++)
{
nxt=(now*now)%val;
if(nxt==1&&now!=1&&now!=val-1)
return false;
now=nxt;
}
if(now!=1)
return false;
}
return true;
}
int main()
{
int AA=0;
//scanf("%d",&t);
long long a;
scanf("%lld",&a);
while(a)
{
AA++;
if(test(a)||a==1)
{
printf("Case %d: %lld\n",AA,a+1);
scanf("%lld",&a);
continue;
}
long long sum=0;
int T=0;
for(int i=2,t=0;i*i<=a;i++)
if(a%i==0)
{
T++;
long long pas=1;
while(a%i==0)
{
a/=i;
pas*=i;
}
sum+=pas;
}
if(a!=1) sum+=a;
if(T==1&&a==1)
printf("Case %d: %lld\n",AA,sum+1);
else
printf("Case %d: %lld\n",AA,sum);
scanf("%d",&a);
}
}