BZOJ2142: 礼物(拓展lucas)
Description
Input
Output
若不存在可行方案,则输出“Impossible”,否则输出一个整数,表示模P后的方案数。
Sample Input
4 2
1
2
Sample Output
解题思路:
这道题就是组合数取模终极版。
很显然要求的就是:

数据范围好像不是很大。
拓展lucas没跑了。
大概思路就是:先将取模数拆分,求出各部分的解,使用中国剩余定理合并答案。
中国剩余定理我就不说了。
这里主要讲一下拓展lucas。
将组合数展开:

这里主要有两个问题需要解决
1.n 太大,一锅煮不下,直接枚举会超时。
2.n 比取模数大时会变成0下面本来有抵消的都没了。
我们一个一个看。
怎么计算n!呢?
我们暴力吧。
我们先看第二个吧。
先说第二个。
既然是抵消了,那么为何不让它先约掉呢。
很显然,将最小质因数p的幂次项提取出就可以完成任务。
也就是说,在处理阶乘时,跳过幂次项。
就是将原式化简成这样:

就解决了。
回来看第一个。
既然要跳过p的次幂,那么就都提出来发现剩余项是前pk以内的数的次幂。
提出来的项可以递归操作。
差不多就是这样了。
我也不知道这和lucas有啥关系
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
lnt prime[];
lnt picie[];
lnt tmp[];
lnt w[];
lnt n,m;
int cnt;
lnt qucp(lnt a,lnt b,lnt c)
{
lnt ans=;
while(b)
{
if(b&)
ans=ans*a%c;
a=a*a%c;
b=b/;
}
return ans%c;
}
void exgcd(lnt a,lnt b,lnt &x,lnt &y)
{
if(!b)
{
x=;
y=;
return ;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
return ;
}
lnt Inv(lnt x,lnt mod)
{
lnt a;
lnt b;
exgcd(x,mod,a,b);
return (a%mod+mod)%mod;
}
lnt Crt(lnt num,lnt *ans,lnt *mod)
{
lnt ret=;
lnt mdl=;
for(int i=;i<=num;i++)
mdl*=mod[i];
for(int i=;i<=num;i++)
{
lnt x=mdl/mod[i];
ret=(ret+x*Inv(x,mod[i])%mdl*ans[i]%mdl)%mdl;
}
return ret;
}
lnt fac(lnt len,lnt pi,lnt pk)
{
if(!len)
return ;
lnt ans=;
for(int i=;i<=pk;i++)
if(i%pi)
ans=ans*i%pk;
ans=qucp(ans,len/pk,pk);
for(int i=;i<=len%pk;i++)
if(i%pi)
ans=ans*i%pk;
return ans*fac(len/pi,pi,pk)%pk;
}
lnt Exlucas(lnt n,lnt m,lnt plc)
{
if(m>n)
return ;
lnt fan=fac(n,prime[plc],picie[plc]);
lnt fam=fac(m,prime[plc],picie[plc]);
lnt fad=fac(n-m,prime[plc],picie[plc]);
lnt ans=fan*Inv(fam,picie[plc])%picie[plc]*Inv(fad,picie[plc])%picie[plc];
lnt c=;
for(int i=n;i;i/=prime[plc])
c+=i/prime[plc];
for(int i=m;i;i/=prime[plc])
c-=i/prime[plc];
for(int i=n-m;i;i/=prime[plc])
c-=i/prime[plc];
return ans*qucp(prime[plc],c,picie[plc])%picie[plc];
}
void brkdn(lnt P)
{
for(int i=;i*i<=P;i++)
{
if(P%i==)
{
cnt++;
prime[cnt]=i;
picie[cnt]=;
while(P%i==)
{
picie[cnt]*=(lnt)(i);
P/=i;
}
}
}
if(P!=)
{
cnt++;
picie[cnt]=prime[cnt]=P;
}
return ;
}
int main()
{
lnt Mod;
scanf("%lld",&Mod);
brkdn(Mod);
scanf("%lld%lld",&n,&m);
lnt sum=;
lnt ans=;
for(int i=;i<=m;i++)
{
scanf("%lld",&w[i]);
sum+=w[i];
}
if(sum>n)
{
puts("Impossible");
return ;
}
for(int i=;i<=m;i++)
{
for(int j=;j<=cnt;j++)
tmp[j]=Exlucas(n,w[i],j);
ans=ans*Crt(cnt,tmp,picie)%Mod;
n-=w[i];
}
printf("%lld\n",ans);
return ;
}
BZOJ2142: 礼物(拓展lucas)的更多相关文章
- 【BZOJ-2142】礼物 拓展Lucas定理
2142: 礼物 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1313 Solved: 541[Submit][Status][Discuss] ...
- [BZOJ2142]礼物(扩展Lucas)
2142: 礼物 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2286 Solved: 1009[Submit][Status][Discuss] ...
- BZOJ2142 礼物 扩展lucas 快速幂 数论
原文链接http://www.cnblogs.com/zhouzhendong/p/8110015.html 题目传送门 - BZOJ2142 题意概括 小E购买了n件礼物,送给m个人,送给第i个人礼 ...
- [bzoj2142]礼物(扩展lucas定理+中国剩余定理)
题意:n件礼物,送给m个人,每人的礼物数确定,求方案数. 解题关键:由于模数不是质数,所以由唯一分解定理, $\bmod = p_1^{{k_1}}p_2^{{k_2}}......p_s^{{k_ ...
- 【bzoj2142】【礼物】拓展Lucas定理+孙子定理
(上不了p站我要死了,侵权度娘背锅) Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量 ...
- 数学:拓展Lucas定理
拓展Lucas定理解决大组合数取模并且模数为任意数的情况 大概的思路是把模数用唯一分解定理拆开之后然后去做 然后要解决的一个子问题是求模质数的k次方 将分母部分转化成逆元再去做就好了 这里贴一份别人的 ...
- 【拓展Lucas】模板
求\(C_n^m \mod p\),写得太丑了qwq. 第一次写拓展Lucas竟然是在胡策的时候qwq写了两个半小时啊_(:з」∠)还写挂了一个地方qwq 当然今天胡策我也是第一次写中国剩余定理(ˇˍ ...
- 拓展Lucas小结
拓展Lucas是解决大组合数取模非质数(尤其是含平方因子的合数)问题的有力工具... 首先对模数质因数分解,把每个质因子单独拎出来处理答案,然后用中国剩余定理(excrt)合并 问题转化为,对于每个质 ...
- BZOJ 3129 [SDOI2013]方程 (拓展Lucas)
题目大意:给定一个方程$X_{1}+X_{2}+X_{3}+X_{4}+...+X_{n}=M$,$\forall X_{i}<=A_{i} (i<=n1)$ $\forall X_{i} ...
随机推荐
- Service绑定模式
Service绑定模式 使用绑定的Service能够实现组件与Service的通信. 组件与被绑定的Service能够不归属于同一个应用程序.因此通过绑定Service能够实现进程间通信. ...
- ORA-01003: no statement parsed
环境:delphi 5.BDE.oracle10 delphi里面用tStoreProc调用存储过程出现ORA-01003: no statement parsed. 解决方法:tStoreProc. ...
- 赵雅智_运用Bitmap和Canvas实现图片显示,缩小,旋转,水印
上一篇已经介绍了Android种Bitmap和Canvas的使用,以下我们来写一个详细实例 http://blog.csdn.net/zhaoyazhi2129/article/details/321 ...
- android系统又一次刷ROM简记(一)
当须要对android系统进行大刀阔斧的改造的时候,应该清晰的了解android各个image的组成才干做到庖丁解牛. 首先在android烧写过程中须要烧写的文件主要包含uboot.bin\boot ...
- Process Monitor —— 程序(文件和注册表)监控
下载地址:Process Monitor v3.33 通过追踪 Process Monitor 的日志,我们可以确认某程序的行为:
- oracle中查询表的信息,包括表名,字段名,字段类型,主键,外键唯一性约束信息
来源于网上整理 总结了一下oracle中查询表的信息,包括表名,字段名,字段类型,主键,外键唯一性约束信息,索引信息查询SQL如下,希望对大家有所帮助: 1.查询出所有的用户表select * fro ...
- VS Code在本地进行调试和打开本地服务器
进行本地调试 1.在扩展中搜索插件 Debugger for Chrome 进行安装.我已经进行了安装,就没有出现安装字样. 2.配置launch.json文件,根据步骤来.file就是你在浏览器中需 ...
- Firewalld 用法解析
其实还是我写的啦 https://www.jianshu.com/p/3444d9413461 1.防火墙firewall的基本概述 现在的RedHat/CentOS7版本默认都使用firewall防 ...
- libc.so.6: version GLIBC_2.14 not found
https://blog.csdn.net/heylun/article/details/78833050
- 基于zookeeper实现分布式配置中心(二)
上一篇(基于zookeeper实现分布式配置中心(一))讲述了zookeeper相关概念和工作原理.接下来根据zookeeper的特性,简单实现一个分布式配置中心. 配置中心的优势 1.各环境配置集中 ...