CF.100633J.Ceizenpok's formula(扩展Lucas)

题目链接
->扩展Lucas

//求C_n^k%m
#include <cstdio>
typedef long long LL;

LL FP(LL x,LL k,LL p)
{
    LL t=1ll;
    for(; k; k>>=1,x=x*x%p)
        if(k&1) t=t*x%p;
    return t;
}
void Exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!b) x=1ll, y=0ll;
    else Exgcd(b,a%b,y,x),y-=a/b*x;
}
LL Inv(LL a,LL mod)
{
//  if(!a) return 0ll;//?
    LL x,y; Exgcd(a,mod,x,y);
    x=(x%mod+mod)%mod;//!
//  if(!x) x=mod;
    return x;
}
LL Fact(LL n,LL pi,LL pk)//factorial Calc n!%(pi^ki) (不计算pi因子 计算C()时提出)
{
    if(!n) return 1ll;
    LL ans=1ll;
    if(n/pk)
    {
        for(LL i=2; i<=pk; ++i)//每pi^ki一循环的部分
            if(i%pi) (ans*=i)%=pk;
        ans=FP(ans,n/pk,pk);//一共n/pk个循环
    }
    for(LL i=2; i<=n%pk; ++i)//pi^ki循环之外的部分 mod pk意义下所以i=2 to n%pk即可
        if(i%pi) (ans*=i)%=pk;
    return ans*Fact(n/pi,pi,pk)%pk;//[n/pi]!部分
}
LL C(LL n,LL m,LL mod,LL pi,LL pk)//Calc C_n^m%(pi^ki)
{
    if(n<m) return 0ll;
    LL a=Fact(n,pi,pk),b=Fact(m,pi,pk),c=Fact(n-m,pi,pk),k=0ll;//k:质因子pi的个数
    for(LL i=n; i; i/=pi) k+=i/pi;//计算x!中pi因子个数:k=f(x)=f(x/pi)+x/pi
    for(LL i=m; i; i/=pi) k-=i/pi;
    for(LL i=n-m; i; i/=pi) k-=i/pi;
    LL ans=a*Inv(b,pk)%pk*Inv(c,pk)%pk*FP(pi,k,pk)%pk;
    return ans*(mod/pk)%mod*Inv(mod/pk,pk)%mod;//这步不是很懂 大概是转到模mod意义下?
}

int main()
{
    LL n,k,mod,ans=0ll;
    scanf("%I64d%I64d%I64d",&n,&k,&mod);
    for(LL now=mod,i=2; i<=mod; ++i)
        if(!(now%i))
        {
            LL pk=1ll;
            while(!(now%i)) pk*=i, now/=i;
            (ans+=C(n,k,mod,i,pk))%=mod;
        }
    printf("%I64d",ans);

    return 0;
}

CF.100633J.Ceizenpok's formula(扩展Lucas)

原文地址:https://www.cnblogs.com/SovietPower/p/8453934.html

时间: 2024-11-12 12:36:25

CF.100633J.Ceizenpok's formula(扩展Lucas)的相关文章

[Codeforces 100633J]Ceizenpok’s formula

Description 求 \[C_n^m \mod p\] \(1\leq m\leq n\leq 10^{18},2\leq p\leq 1000000\) Solution 一般的 \(Lucas\) 是在模数 \(p\) 是质数的条件下适用的.我们来考虑 \(p\) 不是质数的条件. 我们对 \(p\) 进行唯一分解,记 \(p=p_1^{k_1}p_2^{k_2}\cdots p_q^{k_q}\) ,由于形同 \(p_i^{k_i}\) 的部分是互质的,显然我们可以用 \(CRT\)

BZOJ.2142.礼物(扩展Lucas)

题目链接 答案就是C(n,m1) * C(n-m1,m2) * C(n-m1-m2,m3)...(mod p) 使用扩展Lucas求解. 一个很简单的优化就是把pi,pi^ki次方存下来,因为每次分解p都是很慢的. 注意最后p不为1要把p再存下来!(质数) COGS 洛谷上的大神写得快到飞起啊QAQ 就这样吧 //836kb 288ms #include <cmath> #include <cstdio> typedef long long LL; int cnt,P[500],P

[BZOJ2142]礼物(扩展Lucas)

2142: 礼物 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2286  Solved: 1009[Submit][Status][Discuss] Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店中购买了n件礼物,打算送给m个人 ,其中送给第i个人礼物数量为wi.请你帮忙计算出送礼物的方案数(

BZOJ2142 礼物 【扩展Lucas】

题目 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店中购买了n件礼物,打算送给m个人 ,其中送给第i个人礼物数量为wi.请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某 个人在这两种方案中收到的礼物不同).由于方案数可能会很大,你只需要输出模P后的结果. 输入格式 输入的第一行包含一个正整数P,表示模: 第二行包含两个整整数n和m,分别表示小E从商

BZOJ3129 [Sdoi2013]方程 【扩展Lucas】

题目 给定方程 X1+X2+. +Xn=M 我们对第l..N1个变量进行一些限制: Xl < = A X2 < = A2 Xn1 < = An1 我们对第n1 + 1..n1+n2个变量进行一些限制: Xn1+l > = An1+1 Xn1+2 > = An1+2 Xnl+n2 > = Anl+n2 求:在满足这些限制的前提下,该方程正整数解的个数. 答案可能很大,请输出对p取模后的答案,也即答案除以p的余数. 输入格式 输入含有多组数据,第一行两个正整数T,p.T表示

【模板】扩展Lucas随想

扩展Lucas解决的还是一个很Simple的问题: 求:$C_{n}^{m} \; mod \; p$. 其中$n,m$都会比较大,而$p$不是很大,而且不一定是质数. 扩展Lucas可以说和Lucas本身并没有什么关系,重要的是中国剩余定理.扩展Lucas这个算法中教会我们的除了算组合数,还有在模数不是质数的时候,往往可以用$CRT$来合并答案. 将原模数质因数分解:$P = \prod_{i = 1}^{m} p_{i}^{k_{i}}$. 列出$m$个同余方程,第$i$个形如:$C_{n}

扩展lucas定理

i64 POW(i64 a,i64 b,i64 mod) { i64 ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } i64 POW(i64 a,i64 b) { i64 ans=1; while(b) { if(b&1) ans=ans*a; a=a*a; b>>=1; } return ans; } i64 exGcd(i64 a,i64 b,i64 &

[bzoj1951] [Sdoi2010]古代猪文 费马小定理+Lucas定理+CRT

Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃

P54 扩展数字的位表示

背景:不同字长的整数进行转换,需要在不改变数的大小的前提下将较小的数据类型转为更大的数据类型. 无符号数的扩展:开头加0即可,也叫零扩展. 有符号数(补码)的扩展:开头添符号位. 1 short sx = -12345; 2 unsigned short usx = sx; 3 int x = sx; 4 unsigned ux = usx; 5 6 printf("sx = %d:\t", sx); 7 show_bytes((byte_pointer)&sx, sizeof