zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",AA,sum+1);
            else
                printf("Case %d: %lld
    ",AA,sum);
            scanf("%d",&a);
        }
    }
    
  • 相关阅读:
    字符串转换成整型数 atoi()
    求一个正整数各个数位上的数字之和
    求小于等于n的所有素数
    iomanip,setw(),setw: undeclared identifier
    计算机界的牛人前辈
    clrscr( )用法
    printf()
    realloc() 用法详解
    ADO和ADO.NET的区别
    C++中delete和delete[]的区别
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9927167.html
Copyright © 2011-2022 走看看