原文链接http://www.cnblogs.com/zhouzhendong/p/8110015.html


题目传送门 - BZOJ2142


题意概括

  小E购买了n件礼物,送给m个人,送给第i个人礼物数量为wi。计算出送礼物的方案数模P后的结果。
  设P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数。
  对于100%的数据,1≤n≤10^9,1≤m≤5,1≤pi^ci≤10^5。

题解

  首先,我们可以列出答案:
  ans=∑1<=i<=n C(n,n-∑1<=j<i w[j])
  然后算那个C(a,b)显然用n!预处理不行。
  然后我们有一个叫ex_lucas的算法可以搞定他。具体自行百度。

代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long LL;
LL P,n,m,w[5];
LL px[30],py[30],cnt;
bool check(){
int tot=0;
for (int i=1;i<=m;i++)
tot+=w[i];
return tot<=n;
}
void divide_prime(LL x){
cnt=0;
for (LL i=2;x>1&&i*i<=x;i++)
if (x%i==0){
px[++cnt]=i;
while (x%i==0)
x/=i,py[cnt]++;
}
if (x>1)
px[++cnt]=x,py[cnt]=1;
}
LL Pow(LL x,LL y,LL mod){
if (y==0)
return 1LL;
LL xx=Pow(x,y/2,mod);
xx=xx*xx%mod;
if (y&1LL)
xx=xx*x%mod;
return xx;
}
void ex_gcd(LL a,LL b,LL &x,LL &y){
if (!b)
x=1,y=0;
else
ex_gcd(b,a%b,y,x),y-=a/b*x;
}
LL Inv(LL X,LL mod){
if (!X)
return 0;
LL a=X,b=mod,x,y;
ex_gcd(a,b,x,y);
x=(x%b+b)%b;
return x;
}
LL ex_lucas(LL n,LL pi,LL pk){
if (!n)
return 1LL;
LL ans=1;
for (LL i=2;i<=pk;i++)
if (i%pi)
ans=ans*i%pk;
ans=Pow(ans,n/pk,pk);
for (LL i=2;i<=n%pk;i++)
if (i%pi)
ans=ans*i%pk;
return ans*ex_lucas(n/pi,pi,pk)%pk;
}
LL C(LL n,LL m,LL pi,LL pk){
if (m>n)
return 0;
LL a=ex_lucas(n,pi,pk),b=ex_lucas(m,pi,pk),c=ex_lucas(n-m,pi,pk);
LL k=0,ans;
for (LL i=n;i;i/=pi,k+=i);
for (LL i=m;i;i/=pi,k-=i);
for (LL i=n-m;i;i/=pi,k-=i);
ans=a*Inv(b,pk)%pk*Inv(c,pk)%pk*Pow(pi,k,pk)%pk;
return ans*(P/pk)%P*Inv(P/pk,pk)%P;
}
LL C(LL n,LL m){
LL ans=0;
for (int i=1;i<=cnt;i++)
ans=(ans+C(n,m,px[i],Pow(px[i],py[i],P+1)))%P;
return ans;
}
int main(){
scanf("%lld%lld%lld",&P,&n,&m);
for (int i=1;i<=m;i++)
scanf("%lld",&w[i]);
if (!check()){
puts("Impossible");
return 0;
}
divide_prime(P);
LL ans=1;
for (int i=1;i<=m;i++)
ans=ans*C(n,w[i])%P,n-=w[i];
printf("%lld",ans);
return 0;
}

  

 

BZOJ2142 礼物 扩展lucas 快速幂 数论的更多相关文章

  1. [BZOJ2142]礼物(扩展Lucas)

    2142: 礼物 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2286  Solved: 1009[Submit][Status][Discuss] ...

  2. [bzoj2142]礼物(扩展lucas定理+中国剩余定理)

    题意:n件礼物,送给m个人,每人的礼物数确定,求方案数. 解题关键:由于模数不是质数,所以由唯一分解定理, $\bmod  = p_1^{{k_1}}p_2^{{k_2}}......p_s^{{k_ ...

  3. 欧几里得算法(及扩展)&&快速幂(二分+位运算)

    最近在二中苦逼地上课,天天听数论(当然听不懂) 但是,简单的还是懂一点的 1.欧几里得算法 说得这么高级干什么,gcd入门一个月的人都会吧,还需要BB? 证明可参照其他博客(不会),主要就是gcd(a ...

  4. BZOJ - 2142 礼物 (扩展Lucas定理)

    扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...

  5. BZOJ1951 [Sdoi2010]古代猪文 中国剩余定理 快速幂 数论

    原文链接http://www.cnblogs.com/zhouzhendong/p/8109156.html 题目传送门 - BZOJ1951 题意概括 求 GM mod 999911659 M=∑i ...

  6. HDU6395 Sequence(矩阵快速幂+数论分块)

    题意: F(1)=A,F(2)=B,F(n)=C*F(n-2)+D*F(n-1)+P/n 给定ABCDPn,求F(n) mod 1e9+7 思路: P/n在一段n里是不变的,可以数论分块,再在每一段里 ...

  7. [LintCode]快速幂(数论)

    计算a^n % b,其中a,b和n都是32位的整数. 快速幂搞就过了.快速幂首先就是要知道 (a*b)%c = ((a%c)*b)%c ,所以经过推导得出. (a^n)%b = ((((a%b)*a) ...

  8. [CQOI2018]交错序列 (矩阵快速幂,数论)

    [CQOI2018]交错序列 \(solution:\) 这一题出得真的很好,将原本一道矩阵快速幂硬生生加入组合数的标签,还那么没有违和感,那么让人看不出来.所以做这道题必须先知道(矩阵快速幂及如何构 ...

  9. BZOJ.2142.礼物(扩展Lucas)

    题目链接 答案就是C(n,m1) * C(n-m1,m2) * C(n-m1-m2,m3)...(mod p) 使用扩展Lucas求解. 一个很简单的优化就是把pi,pi^ki次方存下来,因为每次分解 ...

随机推荐

  1. 编译和运行dubbo-admin管理平台

      下载   Github上下载最新的dubbo源码包并解压     修改ZooKeeper相关的配置   打开dubbo-admin/src/main/webapp/WEB-INF下的dubbo.p ...

  2. 安装mysql5.7与创建用户和远程登录授权

    环境:ubuntu18.04 参考文章:安装并远程登录授权:https://www.cnblogs.com/chancy/p/9444187.html 用户管理:https://www.cnblogs ...

  3. C# 后台请求api

    /// <summary> /// 指定Post地址使用Get 方式获取全部字符串 /// </summary> /// <param name="url&qu ...

  4. Python-mysql 权限 pymysql 注入共计

    1.mysql用户管理 *** 数据安全非常重要 不可能随便分配root账户 应该按照不同开发岗位分配不同的账户和权限 mysql中 将于用户相关的数据放在mysql库 user - > db ...

  5. redhat7.3安装python3 pip3

    首先系统自带的python是python2 我们需要安装一个python3(这里的所有源码包都可以在环境中准备好,这样没有网也可以进行安装) 安装python 1.安装环境 # yum -y inst ...

  6. 数字、ip转换python实现

    # 数字 ==> ip # 数字范围[0, 255^4] >>> num2ip = lambda x: '.'.join([str(x/(256**i)%256) for i ...

  7. LuoGu P2735 电网 Electric Fences

    题目传送门 这个东西,本来我是用求出两条一次函数解析式然后判断在x坐标下的y坐标值来做的 首先因为没考虑钝角三角形,WA了 然后又因为精度处理不好又WA了 一气之下,只能去网上查了查那个皮克定理 首先 ...

  8. 软件测试-历史bug回顾(持续更新~)

    1.第一次编写程序的时候非常不容易看出的错误就是 = 和 == 的区别. 赋值符号,判断符号之间有着天差地别.导致一直循环错误,一直苦苦找寻愿意无果,一步步看代码解决. 2.对于终结条件判断不是很清楚 ...

  9. JAVA 语言如何进行异常处理,关键字: throws,throw,try,catch,finally分别代表什么意义? 在try块中可以抛 出异常吗?

    Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类, 并提供了良好的接口.        在 Java中,每个异常都是一个对象,它是 Throwable 类或其它子类的实例.当一个方法出 ...

  10. Confluence 6 数据库和临时目录

    数据库 所有的其他数据库,包括有页面,内容都存储在数据库中.如果你安装的 Confluence 是用于评估或者你选择使用的是 Embedded H2 Database 数据库.数据库有关的文件将会存储 ...