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. Web前端之基础知识

    学习web前端开发基础技术须要掌握:HTML.CSS.Javascript 1.HTML是网页内容的载体 内容就是网页制作者放在页面上想要让用户浏览的信息,能够包括文字.图片.视频等. 2.CSS样式 ...

  2. .net core的安装

    安装完成后的路径在C:\Program Files\dotnet https://github.com/dotnet/cli/issues/390 ===2017年06月29日=== 安装成功之后,配 ...

  3. php 扩展

    如何利用PHP扩展函数,扩展出自己的函数等 php扩展函数有哪些zend_parse_parameters() spprintf() RETURN_STRINGL()

  4. POJ 1293 网络流 第一题

    完全的模板,做多了就好了吧 反向流量真的很有意思,有这样一种说法比较容易理解.”正向是+,反向就是-,其实是等价的.因为每次找到的增广路不一定是最优解里面的,所以再进行后面的操作的时候要重新选择,而反 ...

  5. CentOS7的聚合链路

    1.环境介绍 [root@rhcc ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) ENERAL.DEVICE: en ...

  6. AutoLayout具体解释+手把手实战

    首先说一下这篇博客尽管是标记为原创,可是事实并不是本人亲自写出来的.知识点和样例本人花了一天各处查找和整理终于决定写一个汇总的具体解释,解去各位朋友到处盲目查找的必要,由于不是转载某一个人的内容.故此 ...

  7. 利用gradle加入构建版本

    在java的程序中,貌似都没有这个构建版本的概念.用的诸如eclipse. idea和android studio的IDE也没有直接提供构建版本的选项.只是我却想在android程序的版本其中加入一个 ...

  8. mysql_jdbc

    package com.lovo.day18_jdbc1; import java.sql.Connection; import java.sql.DriverManager; import java ...

  9. nagios,zabbix对照

    nagios/zabbix对照: nagios核心功能是监控报警.是一个轻量化的监控系统. 假设须要图标显示,须要添加图标显示插件(如pnp4nagios): 假设须要存入数据库,须要对应的插件(ND ...

  10. js---16继承

    123 instanceof Number;//false,要左边是对象右边是函数 typeof 123 ; //number new Number(123) instanceof Number; / ...