hdu 5407 CRB and Candies(素数筛选法,除法取模(乘法逆元))

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5407

解题思路:

官方题解:

The problem is just to calculate g(N) =\ LCM(C(N,0), C(N,1), ..., C(N, N))g(N) = LCM(C(N,0),C(N,1),...,C(N,N)).

Introducing function f(n) =\ LCM(1, 2, ..., n)f(n) = LCM(1,2,...,n),
the fact g(n) =\ f(n+1) / (n+1)g(n) = f(n+1)/(n+1) holds.

We calculate f(n)f(n) in
the following way.

f(1)=1f(1)=1.

If n =p^{k}n =p?k?? then f(n) =\ f(n-1) \times \ pf(n) = f(n?1)× p,
else f(n) =\ f(n-1)f(n) = f(n?1).

Time complexity:O(N\cdot logN)O(N?logN)

如果不会做,可以取个巧,已知前n项,可以在这个网站找找规律再做。。。http://oeis.org/?language=english

  • LCM((n0),(n1)…(nn))



  • g(n)=LCM((n0),(n1)…(nn))

    以及

    f(n)=LCM(1,2,…n)

    则有

    g(n)=f(n+1)n+1

  • 显然f(1)=1,考虑f(n)的质因数分解形式,知道

    f(n)=???f(n?1)
    * p,f(n?1),if n=pkif n!=pk

    其中p表示一个质数,即判断n是否能表达成某个质数的整数k次方.

  • 最后的除以n+1部分需要用逆元处理一下

证明过程如下:

http://www.zhihu.com/question/34859879/answer/60168919

http://arxiv.org/pdf/0906.2295v2.pdf

首先用素数筛选法求出1~1000000之间的素数,然后再计算f[n],但是计算f(n)的时候不能直接除以(n+1),应乘以其逆元.

下面有两种求逆元的模板:

1.利用扩展欧几里德算法求逆元

ll extend_gcd(ll a,ll b,ll &x,ll &y){
    if(a == 0 && b == 0)
        return -1;//无最大公约数
    if(b == 0){
        x = 1;
        y = 0;
        return a;
    }
    ll d = extend_gcd(b,a%b,y,x);
    y -= a/b*x;
    return d;
}

//*********求逆元素*******************
//ax = 1(mod n)
ll mod_reverse(ll a,ll n)
{
    ll x,y;
    ll d = extend_gcd(a,n,x,y);
    if(d == 1)
        return (x%n+n)%n;
    else
        return -1;
}

2.利用快速幂求逆元

ll pow_mod(ll x, int n) {
    ll ret = 1;
    while (n) {
        if (n&1)
            ret = ret * x % MOD;
        x = x * x % MOD;
        n >>= 1;
    }
    return ret;
}

ll mod_reverse(ll x) {
    return pow_mod(x, MOD-2);
}

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

typedef long long ll;
const int MOD = 1000000007;
const int N = 1000005;
ll f[N];
int nprime;
int vis[N];
int prime[80000];

void getprime(){
    nprime = 0;
    memset(vis,0,sizeof(vis));
    memset(prime,0,sizeof(prime));
    for(int i = 2; i <= N-5; i++){
        int t = (N-5)/i;
        for(int j = 2; j <= t; j++){
            vis[i*j] = 1;
        }
    }
    for(int i = 2; i <= N-5; i++){
        if(!vis[i])
            prime[nprime++] = i;
    }
    memset(vis,0,sizeof(vis));
    for(int i = 0; i < nprime; i++){
        ll a = prime[i];
        ll b = a;
        for(; a < N; a*=b)
            vis[a] = b;
    }
}

void init(){
    getprime();
    f[1] = 1;
    for(int i = 2; i <= N-4; i++){
        if(vis[i])
            f[i] = f[i-1]*vis[i]%MOD;
        else
            f[i] = f[i-1];
        f[i] %= MOD;
    }
}
/*
ll extend_gcd(ll a,ll b,ll &x,ll &y){
    if(a == 0 && b == 0)
        return -1;//无最大公约数
    if(b == 0){
        x = 1;
        y = 0;
        return a;
    }
    ll d = extend_gcd(b,a%b,y,x);
    y -= a/b*x;
    return d;
}

//*********求逆元素*******************
//ax = 1(mod n)
ll mod_reverse(ll a,ll n)
{
    ll x,y;
    ll d = extend_gcd(a,n,x,y);
    if(d == 1)
        return (x%n+n)%n;
    else
        return -1;
}
*/

ll pow_mod(ll x, int n) {
    ll ret = 1;
    while (n) {
        if (n&1)
            ret = ret * x % MOD;
        x = x * x % MOD;
        n >>= 1;
    }
    return ret;
}

ll mod_reverse(ll x) {
    return pow_mod(x, MOD-2);
}

int main(){
    init();
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        //ll ni = mod_reverse(n+1,MOD);
        ll ni = mod_reverse(n+1);
        printf("%lld\n",f[n+1]*ni%MOD);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 12:11:13

hdu 5407 CRB and Candies(素数筛选法,除法取模(乘法逆元))的相关文章

Hdu 5407 CRB and Candies (找规律)

题目链接: Hdu 5407 CRB and Candies 题目描述: 给出一个数n,求lcm(C(n,0),C[n,1],C[n-2]......C[n][n-2],C[n][n-1],C[n][n])%(1e9+7)是多少? 解题思路: 刚开始的时候各种开脑洞,然后卡题卡的风生水起.最后就上了数列查询这个神奇的网站,竟然被我找到了!!!!就是把题目上给的问题转化为求lcm(1, 2, 3, 4 ...... n-2, n-1, n, n-1) / (n+1),扎扎就打了两个表一个lcm[n

HDU 5407——CRB and Candies——————【逆元+是素数次方的数+公式】

CRB and Candies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 722    Accepted Submission(s): 361 Problem Description CRB has N different candies. He is going to eat K candies.He wonders how ma

hdu 5407 CRB and Candies(组合数+最小公倍数+素数表+逆元)暨2015暑期多校赛第10场

题意: 输入n,求c(n,0)到c(n,n)的所有组合数的最小公倍数. 输入: 首行输入整数t,表示共有t组测试样例. 每组测试样例包含一个正整数n(1<=n<=1e6). 输出: 输出结果(mod 1e9+7). 感觉蛮变态的,从比赛开始我就是写的这道题,比赛结束还是没写出来…… 期间找到了逆元,最小公倍数,组合数的各种公式,但是爆了一下午tle. 比赛结束,题解告诉我,公式秒杀法…… 但是公式看不懂,幸好有群巨解说,所以有些听懂了,但还是需要继续思考才能弄懂. 题解: 设ans[i]表示i

HDU 5407 CRB and Candies (2015年多校比赛第10场)

1.题目描述:点击打开链接 2.解题思路:本题要求LCM(C(n,0), C(n,1),..., C(n,n)),官方题解是转化为求解LCM(1,2,3,...n+1)/(n+1),然而这种做法还是觉得太陌生,不妨试着用学过的唯一分解定理去做. 首先,求这n+1个数的LCM,实际上就是求所有小于n的素数中,对于每一个素数Pi,哪一项的指数最大,然后把他们连乘起来即可得到LCM值.因此,问题转化为确定每一个pi的最大指数.这里要用到Kummer定理来解决,Kummer定理告诉我们这样一个事实:p恰

【LCM从1-n】 HDU 5407 CRB and Candies

通道 题意:计算C(n,0)+...C(n,n) 思路:转化为LCM(1...n)/ n 代码: #include <cstdio> #include <bitset> using namespace std; typedef long long ll; const int N = 1000000+2; const ll MOD = (ll)1e9 + 7; ll vis[(N+31)/32 + 5]; int pri[5770000], pnum; ll sum[5770000]

HDU 5407 CRB and Candies(LCM +最大素因子求逆元)

[题目链接]click here~~ [题目大意]求LCM(Cn0,Cn1,Cn2....Cnn)%MOD 的值 [思路]来图更直观: 这个究竟是怎样推出的,说实话.本人数学归纳大法没有推出来,幸得一个大神给定愿文具体证明,点击这里:click here~~ 代码: #include <bits/stdc++.h> using namespace std; const int N=1e6+10; const int MOD=1e9+7; typedef long long LL; LL p[N

HDU 5407 CRB and Candies

传送门 http://oeis.org/A002944 http://oeis.org/A003418 令an=LCM(C(n,0),C(n,1),C(n,2),...,C(n,n)) bn=LCM(1,2,3,...,n) an=bn+1n+1 if (n=pk)bn=p?bn?1elsebn=bn?1 #include <bits/stdc++.h> using namespace std; #define prt(k) cerr<<#k" = "<&

hdu 1452 Happy 2004 (快速幂+取模乘法逆元)

Problem Description Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your job is to determine S modulo 29 (the rest of the division of S by 29).Take X = 1 for an example. The positive integer divisors of

HDU 1164 Eddy&#39;s research I【素数筛选法】

思路:将输入的这个数分成n个素数的相乘的结果,用一个数组存储起来.之后再输出就可以了 Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6633    Accepted Submission(s): 3971 Problem Description Eddy's interest is very ext