Description

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

Input

输入的第一行包含一个正整数P,表示模;
第二行包含两个整整数n和m,分别表示小E从商店购买的礼物数和接受礼物的人数;
以下m行每行仅包含一个正整数wi,表示小E要送给第i个人的礼物数量。

Output

若不存在可行方案,则输出“Impossible”,否则输出一个整数,表示模P后的方案数。

Sample Input

100
4 2
1
2

Sample Output

12

解题思路:

这道题就是组合数取模终极版。

很显然要求的就是:

数据范围好像不是很大。

拓展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)的更多相关文章

  1. 【BZOJ-2142】礼物 拓展Lucas定理

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

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

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

  3. BZOJ2142 礼物 扩展lucas 快速幂 数论

    原文链接http://www.cnblogs.com/zhouzhendong/p/8110015.html 题目传送门 - BZOJ2142 题意概括 小E购买了n件礼物,送给m个人,送给第i个人礼 ...

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

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

  5. 【bzoj2142】【礼物】拓展Lucas定理+孙子定理

    (上不了p站我要死了,侵权度娘背锅) Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量 ...

  6. 数学:拓展Lucas定理

    拓展Lucas定理解决大组合数取模并且模数为任意数的情况 大概的思路是把模数用唯一分解定理拆开之后然后去做 然后要解决的一个子问题是求模质数的k次方 将分母部分转化成逆元再去做就好了 这里贴一份别人的 ...

  7. 【拓展Lucas】模板

    求\(C_n^m \mod p\),写得太丑了qwq. 第一次写拓展Lucas竟然是在胡策的时候qwq写了两个半小时啊_(:з」∠)还写挂了一个地方qwq 当然今天胡策我也是第一次写中国剩余定理(ˇˍ ...

  8. 拓展Lucas小结

    拓展Lucas是解决大组合数取模非质数(尤其是含平方因子的合数)问题的有力工具... 首先对模数质因数分解,把每个质因子单独拎出来处理答案,然后用中国剩余定理(excrt)合并 问题转化为,对于每个质 ...

  9. 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} ...

随机推荐

  1. iOS开发之软键盘使用小技巧

    在iOS开发过程中,有时候须要弹出软键盘进行输入,有时候又须要在某些情况下隐藏软键盘,以提高用户体验. 今天有几个关于软键盘的小技巧和大家分享. (1)仅仅弹出数字键盘 有某些需求中,要求用户仅仅能在 ...

  2. 使用 gradle 在编译时动态设置 Android resValue / BuildConfig / Manifes中&lt;meta-data&gt;变量的值

    转载请标明出处:http://blog.csdn.net/xx326664162/article/details/49247815 文章出自:薛瑄的博客 你也能够查看我的其它同类文章.也会让你有一定的 ...

  3. css如何实现垂直居中(5种方法)

    css如何实现垂直居中(5种方法) 一.总结 一句话总结:行内只需要简单地把 line-height 设置为那个对象的 height 值就可以使文本居中了. 块的话可以尝试 margin:auto: ...

  4. 项目:rbac 基于角色的权限管理系统;

    - 简单示意流程图 - RBAC分析: - 基于角色的权限管理: - 权限等于用户可以访问的URL: - 通过限制URL来限制权限: - RBAC表结构组成: from django.db impor ...

  5. startActivityForResult and onActivityResult

    startActivityForResult and onActivityResult startActivityForResult 开启Activity 组织数据之后 发送,onActivityRe ...

  6. Linux常用Office办公软件

    1.WPS Office是由金山软件股份有限公司自主研发的一款办公软件套件,可以实现办公最常用的文字.表格.演示等多种功能.免费提供海量的在线存储空间及文档模板.支持阅读和输出PDF文件.全面兼容Mi ...

  7. Centos7部署phpMyAdmin系统

    phpMyAdmin是一个使用PHP语言编写,用来管理MYSQL数据库的Web应用系统 一:安装phpMyadmin 下载phpMyadmin最新版本4.8 wget https://files.ph ...

  8. Dcloud+mui 压缩上传图片到服务器

    chooseImgFromAlbums选择图片 chooseImgFromPictures 拍照 changeToLocalUrl 转换成可用的路径 uploadpic.compressImg 压缩图 ...

  9. NOIP 模拟赛

    NOIP 模拟赛 思路:求 n , m 的 gcd,然后用 n , m 分别除以 gcd:若 n 或 m 为偶数,则输出 1/2. 特别的,当 n = m = 1 时,应输出 1/1 #include ...

  10. 【Henu ACM Round#14 C】Duff and Weight Lifting

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 2^y可以由两个2^(y-1)相加得到. 则有一个贪心的策略. 就是2^x尽量都变成2^(x+1) (即能够凑就尽量凑) 如果x还有 ...