卢卡斯定理

卢卡斯定理:解决一类组合数取模问题

A、B是非负整数,p是质数。AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]。

则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0])  modp同余

即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)

这个是单独处理n!的情况,当然C(n,m)就是n!/(m!*(n-m)!),每一个阶乘都用上面的方法处理的话,就是Lucas定理了,注意这儿的p是素数是有必要的。

Lucas最大的数据处理能力是p在10^5左右,不能再大了,hdu 3037就是10^5级别的!

对于大组合数取模,n,m不大于10^5的话,用逆元的方法,可以解决。对于n,m大于10^5的话,那么要求p<10^5,这样就是Lucas定理了,将n,m转化到10^5以内解。

模板:

/*
Lucas定理 C(n,m)%p(p为素数)
C(n,m)与C(a[n],b[n])*C(a[n-1],b[n-1])*C(a[n-2],b[-2])*....*C(a[0],b[0])模p同余
a,b 是n,m在p进制下的数
有的推公式: (C(n%p,m%p,p)*Lcs(n/p,m/p,p))%p;
关键是求 C(n%p,m%p,p) 递归会很慢 for的话会爆掉
这里用一个定理:a/b%p <--> a*x%p  x为b在b%p下的逆元
再来一个定理:x=b^(p-2)   x为b在%p下的逆元  p为素数
然后预处理一下阶乘就ok了
*/
#include<iostream>
#include<cstdio>
#include<cstring>

#define N 1001

using namespace std;
int f[N];

int Mi(int a,int b,int p)
{
    int res=1;
    while(b)
    {
        if(b&1) res=res*a%p;
        b>>=1;a=a*a%p;
    }return res;
}

int C(int n,int m,int p)
{
    if(m>n)return 0;
    return  f[n]*Mi(f[m]*f[n-m],p-2,p)%p;
}

int Lus(int n,int m,int p)
{
    if(m==0) return 1;
    return (C(n%p,m%p,p)*Lus(n/p,m/p,p))%p;
}

int main()
{
    int n,m,p;
    scanf("%d%d%d",&n,&m,&p);
    f[0]=1;
    for(int i=1;i<=p;i++)
      f[i]=f[i-1]*i%p;
    printf("%d\n",Lus(n,m,p));
}
时间: 2024-10-05 19:09:12

卢卡斯定理的相关文章

卢卡斯定理的模板以及应用

定义: Lucas定理是用来求 C(n,m) MOD p,p为素数的值.Lucas定理:我们令n=sp+q,m=tp+r.(q,r≤p) 那么:(在编程时你只要继续对 调用 Lucas 定理即可.代码可以递归的去完成这个过程,其中递归终点为 t=0 :时间复杂度 O(logp(n)?p):) 主要解决当 n,m 比较大的时候,而 p 比较小的时候 <1e6 ,那么我们就可以借助 卢卡斯定理来解决这个问题: 模板: #include <iostream> #include <cstd

cf451E Devu and Flowers 卢卡斯定理+容斥定理

题目:http://codeforces.com/problemset/problem/451/E 题意:有n个盒子(n<=20),每个盒子中有10^12个小球,现从每个盒子中取出若干球(可为0),求共取出s个小球(s<=10^14)的方案数. 组合数学问题,求C(n,m).但n,m过大时,可用卢卡斯定理. 卢卡斯定理:C(n,m) %p = C(n/p,m/p) * C(n%p,m%p) 从n个盒子中取出s个球的方案数,相当于插板,即 C(s+n-1,n-1).注意这是没有限制条件的情况.

Xiao Ming&#39;s Hope 卢卡斯定理的推广。

Xiao Ming's Hope 题目抽象:求C(n,0),C(n,1),……,C(n,n)中奇数的个数. 思路:考察C(n,m)%2. 由卢卡斯定理    C(A,B)=C(a[n-1],b[n-1])*C(a[n-2],b[n-2])* ……*C(a[0],b[0])  ,其中a[i]为A的p进制位 要使C(n,m)%2==1,  那么对于n上的1的位,m上对应的位可以为0,1,(c(1,0)=c(1,1)=1). 对于n上为0的位,m上对应的位必须为0.(c(0,0)=1,c(0,1)=0

洛谷——P3807 【模板】卢卡斯定理

P3807 [模板]卢卡斯定理 题目背景 这是一道模板题. 题目描述 给定n,m,p(1\le n,m,p\le 10^51≤n,m,p≤10?5??) 求 C_{n+m}^{m}\ mod\ pC?n+m?m?? mod p C表示组合数. 一个测试点内包含多组数据. 输入输出格式 输入格式: 第一行一个整数T(T\le 10T≤10),表示数据组数 第二行开始共T行,每行三个数n m p,意义如上 输出格式: 共T行,每行一个整数表示答案. 输入输出样例 输入样例#1: 2 1 2 5 2

【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)

4403: 序列统计 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 653  Solved: 320 Description 给定三个正整数N.L和R,统计长度在1到N之间,元素大小都在L到R之间的单调不降序列的数量.输出答案对10^6+3取模的结果. Input 输入第一行包含一个整数T,表示数据组数.第2到第T+1行每行包含三个整数N.L和R,N.L和R的意义如题所述. Output 输出包含T行,每行有一个数字,表示你所求出的答案对106+3

【BZOJ 1272】 1272: [BeiJingWc2008]Gate Of Babylon (容斥原理+卢卡斯定理)

1272: [BeiJingWc2008]Gate Of Babylon Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 254  Solved: 120 Description Input Output Sample Input Sample Output 12 HINT Source [分析] T很小,跟以前的某一题很像啊,就是容斥. 枚举不符合的(超过限制的),2^t,然后就是算 n种无限多的东东中选m个. 经典的组合数题,$C_{n+m-1

【BZOJ 2982】 2982: combination (卢卡斯定理)

2982: combination Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 510  Solved: 316 Description LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样.那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案mod 10007的值.(1<=m<=n<=200,000,000) Input   第一行一个整数t,表示有t组数据.(t&l

HDU 5794 A Simple Chess(卢卡斯定理 + 容斥原理)

传送门 A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 667    Accepted Submission(s): 168 Problem Description There is a n×m board, a chess want to go to the position (n,m) from the

洛谷 P3807 【模板】卢卡斯定理

题目背景 这是一道模板题. 题目描述 给定n,m,p(1\le n,m,p\le 10^51≤n,m,p≤105) 求 C_{n+m}^{m}\ mod\ pCn+mm? mod p 保证P为prime C表示组合数. 一个测试点内包含多组数据. 输入输出格式 输入格式: 第一行一个整数T(T\le 10T≤10),表示数据组数 第二行开始共T行,每行三个数n m p,意义如上 输出格式: 共T行,每行一个整数表示答案. 输入输出样例 输入样例#1: 复制 2 1 2 5 2 1 5 输出样例#