zoukankan      html  css  js  c++  java
  • HDU4344(大数分解)

    题目:Mark the Rope

    题意就是给一个数,然后求这个数的所有因子中组成的最大的一个子集,其中1和本身除外,使得在这个子集中元素两两互素,求最大子集的元素个

    数,并且求出和最大的值。

    找规律就不难发现其实答案就是先大数分解n,例如,180=2^2*3^2*5,那么就输出3   18   ,这两个数分别是素因子的个数和2^2,3^2,5的和。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    
    const int Times=10;
    const int N=550;
    
    using namespace std;
    typedef unsigned __int64 LL;
    
    LL ct,cnt;
    LL fac[N],num[N];
    
    LL gcd(LL a,LL b)
    {
        return b? gcd(b,a%b):a;
    }
    
    LL multi(LL a,LL b,LL m)
    {
         LL ans=0;
         while(b)
         {
             if(b&1)
             {
                 ans=(ans+a)%m;
                 b--;
             }
             b>>=1;
             a=(a+a)%m;
         }
         return ans;
    }
    
    LL quick_mod(LL a,LL b,LL m)
    {
         LL ans=1;
         a%=m;
         while(b)
         {
             if(b&1)
             {
                 ans=multi(ans,a,m);
                 b--;
             }
             b>>=1;
             a=multi(a,a,m);
         }
         return ans;
    }
    
    bool Miller_Rabin(LL n)
    {
        if(n==2) return true;
        if(n<2||!(n&1)) return false;
        LL a,m=n-1,x,y;
        int k=0;
        while((m&1)==0)
        {
            k++;
            m>>=1;
        }
        for(int i=0;i<Times;i++)
        {
            a=rand()%(n-1)+1;
            x=quick_mod(a,m,n);
            for(int j=0;j<k;j++)
            {
                y=multi(x,x,n);
                if(y==1&&x!=1&&x!=n-1) return false;
                x=y;
            }
            if(y!=1) return false;
        }
        return true;
    }
    
    LL Pollard_rho(LL n,LL c)
    {
         LL x,y,d,i=1,k=2;
         y=x=rand()%(n-1)+1;
         while(true)
         {
             i++;
             x=(multi(x,x,n)+c)%n;
             d=gcd((y-x+n)%n,n);
             if(1<d&&d<n) return d;
             if(y==x) return n;
             if(i==k)
             {
                 y=x;
                 k<<=1;
             }
         }
    }
    
    void find(LL n,int c)
    {
         if(n==1) return;
         if(Miller_Rabin(n))
         {
             fac[ct++]=n;
             return ;
         }
         LL p=n;
         LL k=c;
         while(p>=n) p=Pollard_rho(p,c--);
         find(p,k);
         find(n/p,k);
    }
    
    int main()
    {
        int t;
        LL n,ans;
        scanf("%d",&t);
        while(t--)
        {
             scanf("%I64u",&n);
             ct=0;
             find(n,120);
             sort(fac,fac+ct);
             num[0]=1;
             int k=1;
             for(int i=1;i<ct;i++)
             {
                 if(fac[i]==fac[i-1])
                     ++num[k-1];
                 else
                 {
                     num[k]=1;
                     fac[k++]=fac[i];
                 }
             }
             cnt=k;
             LL ret=0;
             for(int i=0;i<cnt;i++)
             {
                 LL temp=1;
                 for(int j=0;j<num[i];j++)
                     temp*=fac[i];
                 ret+=temp;
             }
             if(cnt==1) ret/=fac[0];
             printf("%I64u %I64u
    ",cnt,ret);
        }
        return 0;
    }
    


     

  • 相关阅读:
    BZOJ 2055 80人环游世界 有上下界最小费用可行流
    BZOJ 2406 LuoguP4194 矩阵 有上下界可行流
    BZOJ4873 LuoguP3749 寿司餐厅
    51nod 1551 集合交易 最大权闭合子图
    BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流
    [CodeForces]460C Present
    [BZOJ5072] 小A的树
    [TJOI2015]组合数学
    [HNOI2006]鬼谷子的钱袋
    [IOI2007]矿工配餐
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3157383.html
Copyright © 2011-2022 走看看