【BZOJ2142】礼物(扩展lucas定理,中国剩余定理合并方程)
题意:有n件礼物,m个人,每个人分别需要w[i]件礼物,求分礼物的不同方案数 mod P
提示:设P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数。
1≤n≤10^9,1≤m≤5,1≤pi^ci≤10^5。
P不一定为质数
思路:经推导答案即为n!/(w[i]!),i=1..n
考虑P不是质数
将P分解为提示中所说的形式,可以发现所有pt^ct都是互质的,所以我们可以用下图的中国剩余定理合并

From http://blog.csdn.net/popoqqq/article/details/39891263
然后对于每个pi^ai,我们进行以下处理:
将分子和分母化为x*pi^y的形式
然后分母的x部分与pi互质,可以求逆元,分子分母的y部分直接相减即可
然后我们处理阶乘
以19为例,将19!化为x*pi^y的形式,其中pi=3,ai=2 则有
19!%9=(1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19) %9
=(1*2*4*5*7*8*10*11*13*14*16*17*19)*3^6*(1*2*3*4*5*6) %9
式子的左半部分是不为3的倍数的数,存在长度为p^a的循环节 求出一个循环节 快速幂处理 然后处理剩余部分
右半部分是6!%9 递归处理即可
用这样的思路就可以换解决C(n,m) mod p,p不为质数的情况了
var a:array[..]of int64;
n,m,i:longint;
ans,s,mo:int64; function mult(x,y,p:int64):int64;
var tmp:int64;
begin
mult:=; tmp:=x;
while y> do
begin
if y and = then mult:=mult*tmp mod p;
tmp:=tmp*tmp mod p;
y:=y>>;
end;
end; procedure exgcd(a,b:int64;var d,x,y:int64);
begin
if b= then
begin
d:=a; x:=; y:=;
end
else
begin
exgcd(b,a mod b,d,y,x);
y:=y-(a div b)*x;
end;
end; function inv(a,n:int64):int64;
var d,x,y:int64;
begin
exgcd(a,n,d,x,y);
if d= then exit((x+n) mod n);
exit(-);
end; function fac(n,p,pr:int64):int64;
var i,re,r:int64;
begin
if n= then exit();
re:=; i:=;
while i<=pr do
begin
if i mod p> then re:=re*i mod pr;
inc(i);
end; re:=mult(re,n div pr,pr);
r:=n mod pr;
i:=;
while i<=r do
begin
if i mod p> then re:=re*i mod pr;
inc(i);
end; exit(re*fac(n div p,p,pr) mod pr);
end; function c(n,m,p,pr:int64):int64;
var x,y,z,t,tmp:int64;
begin
if n<m then exit();
x:=fac(n,p,pr);
y:=fac(m,p,pr);
z:=fac(n-m,p,pr);
c:=;
t:=n;
while t> do
begin
c:=c+t div p;
t:=t div p;
end;
t:=m;
while t> do
begin
c:=c-t div p;
t:=t div p;
end;
t:=n-m;
while t> do
begin
c:=c-t div p;
t:=t div p;
end;
tmp:=x*inv(y,pr) mod pr*inv(z,pr) mod pr*mult(p,c,pr) mod pr;
exit(tmp*(mo div pr) mod mo*inv(mo div pr,pr) mod mo);
end; function lucas(n,m:int64):int64;
var x,re,i,pr:int64;
begin
i:=; x:=mo; re:=;
while i<=x do
begin
if x mod i= then
begin
pr:=;
while x mod i= do
begin
x:=x div i; pr:=pr*i;
end;
re:=(re+c(n,m,i,pr)) mod mo;
end;
inc(i);
end;
exit(re);
end; begin
assign(input,'bzoj2142.in'); reset(input);
assign(output,'bzoj2142.out'); rewrite(output);
readln(mo);
readln(n,m);
for i:= to m do
begin
read(a[i]); s:=s+a[i];
end;
if s>n then
begin
writeln('Impossible');
close(input);
close(output);
exit;
end;
ans:=;
for i:= to m do
begin
ans:=ans*lucas(n,a[i]) mod mo;
n:=n-a[i];
end;
writeln(ans); close(input);
close(output);
end.
【BZOJ2142】礼物(扩展lucas定理,中国剩余定理合并方程)的更多相关文章
- [bzoj2142]礼物(扩展lucas定理+中国剩余定理)
题意:n件礼物,送给m个人,每人的礼物数确定,求方案数. 解题关键:由于模数不是质数,所以由唯一分解定理, $\bmod = p_1^{{k_1}}p_2^{{k_2}}......p_s^{{k_ ...
- BZOJ - 2142 礼物 (扩展Lucas定理)
扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...
- [BZOJ2142]礼物(扩展Lucas)
2142: 礼物 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2286 Solved: 1009[Submit][Status][Discuss] ...
- bzoj2142 礼物——扩展卢卡斯定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2142 前几天学了扩展卢卡斯定理,今天来磕模板! 这道题式子挺好推的(连我都自己推出来了) , ...
- BZOJ2142 礼物 扩展lucas 快速幂 数论
原文链接http://www.cnblogs.com/zhouzhendong/p/8110015.html 题目传送门 - BZOJ2142 题意概括 小E购买了n件礼物,送给m个人,送给第i个人礼 ...
- 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)
J. Ceizenpok’s formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- Lucas定理和扩展Lucas定理
1.Lucas定理 首先给出式子:\(C_n^m\%p = C_{\lfloor\frac{n}{p}\rfloor}^{\lfloor\frac{m}{p}\rfloor} * C_{n\%p}^{ ...
- 【learning】 扩展lucas定理
首先说下啥是lucas定理: $\binom n m \equiv \binom {n\%P} {m\%P} \times \binom{n/P}{m/P} \pmod P$ 借助这个定理,求$\bi ...
- Ceizenpok’s formula Gym - 100633J 扩展Lucas定理 + 中国剩余定理
http://codeforces.com/gym/100633/problem/J 其实这个解法不难学的,不需要太多的数学.但是证明的话,我可能给不了严格的证明.可以看看这篇文章 http://ww ...
- [笔记] 扩展Lucas定理
[笔记] 扩展\(Lucas\)定理 \(Lucas\)定理:\(\binom{n}{m} \equiv \binom{n/P}{m/P} \binom{n \% P}{m \% P}\pmod{P} ...
随机推荐
- D. Dasha and Very Difficult Problem 二分
http://codeforces.com/contest/761/problem/D c[i] = b[i] - a[i],而且b[]和a[]都属于[L, R] 现在给出a[i]原数组和c[i]的相 ...
- 微信小程序flex布局
一.flex布局基础 二.相对定位和绝对定位 flex的容器和元素 主轴(左-右),交叉轴(上-下) flex容器属性详解 flex-direction 决定元素的排列方向(默认row ...
- php防止页面刷新代码
//代理IP直接退出 empty($_SERVER['HTTP_VIA']) or exit('Access Denied'); //防止快速刷新 session_start(); $seconds ...
- 阿里云服务器安装ss使用
下载安装服务器版shadowsocks yum install epel-release yum update yum install python-setuptools m2crypto super ...
- bat 时间 的运算与提取
比如在系统中date这个环境变量的值为 -- 星期六 年------%date:~,% 表示从左向右指针向右偏0位,然后从指针偏移到的位置开始提取4位字符,结果是2011 月------%date:~ ...
- widows&l ubuntu 简单互联——基于samba
只是简单访问对方文件,就不上SSH了 windows端访问ubuntu: 要共享的文件夹右键 → 本地网络共享:共享此目录. 会提示你安装一个协议包,即samba(但此处默认安装包不完整),安装成功后 ...
- pdf 使用模板下载
//根据模板下载模板 /** * * 政策5-8条的创建的pdf的模板 */public String createPdfCashTemplate(PdfCashParam pdfCashParam) ...
- C# 处理年月日提取时间
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Win10上 visual studio设置为本地IIS运行网站时 必须以管理员身份加载项目的解决方法
右键,选择“兼容性疑难解答”. 选择“疑难解答程序” 选择“该程序需要附加权限” 点击测试程序 点击下一步 选择 是,为此程序保存这些设置
- Java IO(二)--RandomAccessFile基本使用
RandomAccessFile: 翻译过来就是任意修改文件,可以从文件的任意位置进行修改,迅雷的下载就是通过多个线程同时读取下载文件.例如,把一个文件分为四 部分,四个线程同时下载,最后进行内容拼接 ...