FZU 2020-组合(Lucas定理+逆元解决大组合数求模)

题目地址:FZU 2020

题意:求C(n,m)%p的值(1 <= m <= n <= 10^9, m <= 10^4, m < p < 10^9, p是素数)。

思路:

对于并且p是素数,我们一般采用Lucas定理来解。

1).Lucas定理是用来求 C(n,m) mod p的值,p是素数。其描述为:

如果

那么得到

Lucas(n,m,p)=C(n%p,m%p)* Lucas(n/p,m/p,p)

Lucas(n,0,p)=1;

2).对于大组合数求模C(N,M)%P=N! / (M! * (N-M)! ) % mod

=( N-M+i )! / M!*(i>=1&&i<=M)。然后根据乘法逆元将除法变成乘法即可。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef __int64 LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
using namespace std;
LL n,m,mod;
LL modxp(LL a,LL b)
{
    LL res=1;
    while(b>0) {
        if(b&1)
            res=res*a%mod;
        b=b>>1;
        a=a*a%mod;
    }
    return res;
}

LL C(LL n, LL m)
{
    if(m>n) return 0;
    LL ans=1;
    for(int i=1; i<=m; i++) {
        LL a=(n+i-m)%mod;
        LL b=i%mod;
        ans=ans*(a*modxp(b, mod-2)%mod)%mod;
    }
    return ans;
}
LL Lucas(LL n,LL m)
{
    if(m==0) return 1;
    return C(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%lld %lld %lld",&n,&m,&mod);
        printf("%lld\n",Lucas(n,m));
    }
    return 0;
}

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

时间: 2025-01-04 08:53:04

FZU 2020-组合(Lucas定理+逆元解决大组合数求模)的相关文章

FZU 2020 组合 (Lucas定理)

题意:中文题. 析:直接运用Lucas定理即可.但是FZU好奇怪啊,我开个常数都CE,弄的工CE了十几次,在vj上还不显示. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream>

组合 Lucas定理

组合 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u [Submit]   [Go Back]   [Status] Description 给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数.例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值! Input 输入数据第一行是一个正

Lucas定理--大组合数取模 学习笔记

维基百科:https://en.wikipedia.org/wiki/Lucas%27_theorem?setlang=zh 参考:http://blog.csdn.net/pi9nc/article/details/9615359 http://hi.baidu.com/lq731371663/item/d7261b0b26e974faa010340f http://hi.baidu.com/j_mat/item/8e3a891c258c4fe9dceecaba 综合以上参考,我做的一下总结:

大组合数取模之lucas定理模板,1&lt;=n&lt;=m&lt;=1e9,1&lt;p&lt;=1e6,p必须为素数

typedef long long ll; /********************************** 大组合数取模之lucas定理模板,1<=n<=m<=1e9,1<p<=1e6,p必须为素数 输入:C(n,m)%p 调用lucas(n,m,p) 复杂度:min(m,p)*log(m) ***********************************/ //ax + by = gcd(a,b) //传入固定值a,b.放回 d=gcd(a,b), x , y

Lucas定理的运用及组合数奇偶性的判断

组合数奇偶性的判断 对于C(n,k),若n&k == k 则c(n,k)为奇数,否则为偶数. 最直观的方法就是计算一下,然后看它的奇偶性:但是这个时间以及数据范围上都不允许: 另外一种方法就是,对于给定C(n,m),检查n中2因子的个数与m和(n-m)中2因子个数和的关系,假设n!中2因子个数为a,m!中2因子个数为b,(n-m)!中2因子个数为c,则显然有a>=(b+c):并且当a==b+c时,一定为奇,否则为偶.题意转化为求a和b+c.求一个阶乘中含有的素因子i的个数的方法可以参见Knu

nefu 628大组合数取模

题目连接:http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=628 关于ACM培训的通知 Garden visiting Problem : 628 Time Limit : 1000ms Memory Limit : 65536K description There is a very big garden at Raven's residence. We regard the garden as an n*m rect

大组合数取模

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1119 考虑从(1,1)->(n,m)必定会向下走n-1步,向右走m-1步,那么总的走法是C(n-1+m-1,m-1). 关于组合数取模:大神博客:http://blog.csdn.net/acdreamers/article/details/8037918 1 #include <iostream> 2 #include <string.h> 3 #

FZU 2020 :组合 【lucas】

Problem Description 给出组合数C(n,m), 表示从n个元素中选出m个元素的方案数.例如C(5,2) = 10, C(4,2) = 6.可是当n,m比较大的时候,C(n,m)很大!于是xiaobo希望你输出 C(n,m) mod p的值! 思路:水题,练一下lucas #include<iostream>#include<cstdio>#include <math.h>#include<algorithm>#include<stri

组合数学+lucas定理+逆元 BZOJ2111 [ZJOI2010]Perm 排列计数

2111: [ZJOI2010]Perm 排列计数 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2118  Solved: 563[Submit][Status][Discuss] Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值 Input 输入文件的第一行包含两个