HDU 3988 大数分解

题意:

    

这题把k素因子分解后看n!中有多少个与k对应的素因子。

n!中含有素因子p的个数为n/p+n/p^2.....取整。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;
const unsigned long long oo=9223372036854775808ULL;
ll gcd(ll a,ll b)
{
    return (b==0)?a:gcd(b,a%b);
}
ll Mulmod(ll a,ll b,ll n)
{
    ll  exp = a%n, res = 0;
    while(b)
    {
        if(b&1)
        {
            res += exp;
            if(res>n) res -= n;
        }
        exp <<= 1;
        if(exp>n)
            exp -= n;
        b>>=1;
    }
    return res;
}
ll exp_mod(ll a,ll b,ll c)
{
    ll k = 1;
    while(b)
    {
        if(b&1)
            k = Mulmod(k,a,c);
        a = Mulmod(a,a,c);
        b>>=1;
    }
    return k;
}
bool Miller_Rabbin(ll n, ll times)
{
    if(n==2)return 1;
    if(n<2||!(n&1))return 0;

    ll a, u=n-1, x, y;
    int t=0;
    while(u%2==0)
    {
        t++;
        u/=2;
    }
    srand(100);
    for(int i=0; i<times; i++)
    {
        a = rand() % (n-1) + 1;
        x = exp_mod(a, u, n);
        for(int j=0; j<t; j++)
        {
            y = Mulmod(x, x, n);
            if ( y == 1 && x != 1 && x != n-1 )
                return false; //must not
            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(1)
    {
        i++;
        x = (Mulmod(x,x,n) + c)%n;
        d = gcd((x-y+n)%n,n);
        if(d>1&&d<n)
            return d;
        if(x==y)
            return n;
        if(i==k)
        {
            k<<=1;
            y = x;
        }
    }
}
ll factor[550],tol;
void Find_factor(ll n,ll c)
{
    if(n==1)
        return;
    if(Miller_Rabbin(n,10))
    {
        factor[tol++] = n;
        return;
    }
    ll p = n;
    ll k = c;
    while(p>=n)
        p = Pollard_Rho(p,c--);
    Find_factor(p,k);
    Find_factor(n/p,k);
}
int main()
{
    int t,ca=0,num;
    unsigned long long n,k,fac[550][2];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%I64u%I64u",&n,&k);
        printf("Case %d: ",++ca);
        if(k==1)
        {
            puts("inf");
            continue;
        }
        tol=0;
        Find_factor(k,120);
        unsigned long long ans=oo;
        sort(factor,factor+tol);
        num=0;
        memset(fac,0,sizeof(fac));
        fac[0][0]=factor[0],fac[0][1]=1;
        for(int i=1; i<tol; i++)
        {
            if(fac[num][0]!=factor[i])
                num++,fac[num][0]=factor[i];
            fac[num][1]++;
        }
        for(int i=0; i<=num; i++)
        {
            unsigned long long wans=0,wdiv=fac[i][0],d=n;
            while(d)
                wans+=d/wdiv,d/=wdiv;
            ans=min(ans,wans/fac[i][1]);
        }
        if(ans==oo)
            puts("inf");
        else
            printf("%I64u\n",ans);
    }
    return 0;
}
时间: 2024-11-05 16:23:26

HDU 3988 大数分解的相关文章

HDU 4344 大数分解

题意:给出一条长n的绳子,则有很多长为L的均分方法,找出一个L的集合,集合内元素两两不互素,并且要求元素最多,然后求和. 很容易看出来,有多少个素因子就有多少个元素,再把求出次幂求和就行,我的模板超时..网上找了模板. #include <cstdio> #include <cstring> #include <cstdlib> #include <map> using namespace std; typedef __int64 ll; ll gcd(ll

HDU 3123 大数阶乘取模

题意:Output the answer of (0! + 1! + 2! + 3! + 4! + ... + n!)%m. 这题想难了,暴力就行的东西我竟然素因子分解那么做了,这么做素数的时候比暴力慢,不是素数的时候我也不知道快不快.. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 11

HDU 1042(大数阶乘到10000)

//123*20 相当于 100*20 + 20*20+3 //常规方法N>=13就溢出 #include<stdio.h> #include<string.h> #include<stdlib.h> #define N 10000//因为每位里存储的是小于10000的数,所以缩小4倍 int vis[N]; int main() { int i,j,m; int c,temp; while(scanf("%d",&m)!=EOF) /

POJ题目分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

RSA算法介绍

2.1.1     算法实现 首先, 找出三个数, p, q, r,其中 p, q 是两个相异的质数, r 是与 (p-1)(q-1) 互质的数.p, q, r 这三个数便是 private key 接著, 找出 m, 使得 rm == 1 mod (p-1)(q-1) 这个 m 一定存在, 因为 r 与 (p-1)(q-1) 互质, 用辗转相除法就可以得到了 再来, 计算 n = pq m, n 这两个数便是 public key 编码过程是, 若资料为 a, 将其看成是一个大整数, 假设 a

不算退役贴的退役贴

         就好像大二才学Java一样,这文章也是先写在记事本上的.本来得了铜牌还写退役贴确实没啥意思,但是看了看之前空间里那么幼稚的日志就发现不写点什么好像大学三年什么都没有做.其实写这东西确实不算是纪念ACM生涯的,嗯而是用来纪念一下我的大学的.          Txt没有换行,我又用了word...还记得高中自己不努力,放假就去银河战舰跟着大白,圆心那些人,就好像各自有各自事业一样的,我往死里玩头文字d3,玩的时候后面也有一群人看也挺骄傲嘛哈哈.          转眼间到了高考,

NOD 1171 x^2+y^2=N

1171 . 两个数的平方和 V2 时间限制:1 秒 空间限制:65536 KB 分值: 1280 给出一个整数N,将N表示为2个整数i j的平方和(i <= j),如果有多种表示,按照i的递增序输出. 例如:N = 130,130 = 3^2 + 11^2 = 7^2 + 9^2 (注:3 11同11 3算1种) Input 一个数N(1 <= N <= 10^18) Output 共K行:每行2个数,i j,表示N = i^2 + j^2(0 <= i <= j). 如果

WSE3.0构建Web服务安全(2)

WSE3.0构建Web服务安全(2)非对称加密.公钥.密钥.证书.签名的区别和联系以及X.509 证书的获得和管理 上一节文章WSE3.0构建Web服务安全(1):WSE3.0安全机制与实例开发,写处来以后感觉还是需要补充一下这个加密相关概念的文章,因为很多概念容易混淆,在理解WSE3.0构建Web服务安全的时候遇到了麻烦.为了更好第学习WSE3.0编程开发,我特地整理了加密.公钥.证书.签名的知识点,来阐述这些概念的区别和联系,最后会详细介绍X.509 证书的信息,以及如何的获得X.509 证

把网友的RSA加密代码转换到C#

加密|转换 实际没做什么事情,想起来也无耻,不过可能有些朋友比较懒的话,也会有一点用的.在此先向 duduwolf 表示歉意再说. 嘟嘟狼的原文如下:http://dev.csdn.net/develop/article/30/30182.shtm 我的无耻成果如下(有些地方作了一些小调整): #region Using directives using System;using System.Collections.Generic;using System.Text;using System.