2142: 礼物

Description

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

Input

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

Output

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

数据规模和约定

设 $ P = \prod_{i=1}^n p_i^{c_i} $ 且 $ p_i $ 为质数

$1 \leqslant n \leqslant 10^9,1 \leqslant m \leqslant 5,1 \leqslant p_i^{c_i} \leqslant 10^5 $。

拓展卢卡斯和中国剩余定理的裸题

题目可以转换为求

\[\prod_{i=1}^n C_{n- \sum_{j=0}^{i-1} w[j]}^{w[i]}
\]

剩下的就是求 $ C_n^m % p $ 的问题了。

因为n,m,p都很大,所以我们可以使用拓展卢卡斯求出对于每个 $ p_i^{c_i} $ 余数,然后通过中国剩余定理合并即可。

#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
#define pii pair<ll,ll>
typedef long long ll;
inline int read(){
int x;
char c;
int f=1;
while((c=getchar())!='-' && (c<'0' || c>'9'));
if(c=='-') c=getchar(),f=-1;
x=c^'0';
while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
return x*f;
}
inline ll readll(){
ll x;
char c;
ll f=1;
while((c=getchar())!='-' && (c<'0' || c>'9'));
if(c=='-') c=getchar(),f=-1;
x=c^'0';
while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
return x*f;
}
vector<pii> vc;
ll ksm(ll x,ll y,ll mod){
ll res=1;
while(y){
if(y&1ll) res=res*x%mod;
x=x*x%mod;
y>>=1ll;
}
return res;
}
ll exgcd(ll &x,ll &y,ll a,ll b){
if(!b){
x=1,y=0;
return a;
}
ll res=exgcd(y,x,b,a%b);
y-=a/b*x;
return res;
}
ll inv(ll a,ll b){
a%=b;
ll x,y;
exgcd(x,y,a,b);
x=(x%b+b)%b;
if(!x) x+=b;
return x;
}
ll fac(ll x,ll u,ll mod){
if(!x || x==1) return 1;
ll ans=1,num=1;
if(x/mod){
for(ll i=2;i<mod;++i)
if(i%u) num=num*i%mod;
ans=ans*ksm(num,x/mod,mod);
}
ans=ans*fac(x/u,u,mod)%mod;
x%=mod;
for(ll i=2;i<=x;++i)
if(i%u) ans=ans*i%mod;
return ans;
}
ll calc(ll x,ll u){
ll res=0;
for(;x;x/=u) res+=x/u;
return res;
}
ll C(ll n,ll m,ll u,ll v){
ll x=fac(n,u,v),y=fac(m,u,v),z=fac(n-m,u,v);
// cout<<n<<' '<<m<<' '<<v<<' '<<x<<' '<<y<<' '<<z<<endl;
ll num=calc(n,u)-calc(m,u)-calc(n-m,u);
x=x*inv(y,v)%v*inv(z,v)%v;
return x*ksm(u,num,v)%v;
}
ll exLucas(ll n,ll m,ll mod){
if(m>n) return 0;
ll ans=0;
REP(i,0,vc.size()-1){
pii u=vc[i];
ll x=u.first,y=u.second;
ans=(ans+inv(mod/y,y)*(mod/y)%mod*C(n,m,x,y)%mod)%mod;
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("china.in","r",stdin);
freopen("china.out","w",stdout);
#endif
ll mod=readll(),n=readll(),ans=1;
int m=read(),u=mod;
for(ll i=2;i*i<=u;++i){
if(u%i) continue;
ll x=1;
while(u%i==0) u/=i,x*=i;
vc.push_back(make_pair(i,x));
// cout<<i<<' '<<x<<endl;
}
if(u!=1) vc.push_back(make_pair(u,u));
// cout<<u<<endl;
REP(i,1,m){
ll x=readll();
ans=ans*exLucas(n,x,mod)%mod;
if(!ans){
printf("Impossible\n");
return 0;
}
n-=x;
}
printf("%lld\n",ans);
return 0;
}

bzoj2142: 礼物的更多相关文章

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

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

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

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

  3. BZOJ2142礼物——扩展卢卡斯

    题目描述 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店中购买了n件礼 ...

  4. BZOJ2142 礼物 【扩展Lucas】

    题目 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店中购买了n件礼物, ...

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

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

  6. BZOJ2142: 礼物(拓展lucas)

    Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店 ...

  7. bzoj2142 礼物——扩展卢卡斯定理

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2142 前几天学了扩展卢卡斯定理,今天来磕模板! 这道题式子挺好推的(连我都自己推出来了) , ...

  8. 【BZOJ2142】礼物(拓展卢卡斯定理)

    [BZOJ2142]礼物(拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 显然如果\(\sum w_i>n\)无解. 否则答案就是:\(\displaystyle \prod_{i=1}^m{n- ...

  9. 【BZOJ2142】礼物 组合数+CRT

    [BZOJ2142]礼物 Description 小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi.请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在 ...

随机推荐

  1. Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心

    传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...

  2. 绍一集训Round#1

    到了之后看题,T1一看发现真熟悉,和之前做的一道题真的像,然后内心: 这里是绍一啊,不可能就出这么简单的题 我题意没理解错啊,这不是单独计算每条边的贡献么 维护一个人数的大小,然后直接搞一波就可以了吧 ...

  3. 五年.net程序员Java学习之路

    大学毕业后笔者进入一家外企,做企业CRM系统开发,那时候开发效率最高的高级程序语言,毫无疑问是C#.恰逢公司也在扩张,招聘了不少.net程序员,笔者作为应届生,也乐呵呵的加入到.net程序员行列中. ...

  4. [T-ARA N4/二段横踢][Can We Love]

    歌词来源:http://music.163.com/#/song?id=26310867 Can We Love Can We Love [Can We Love Can We Love] Can W ...

  5. Mongo 开发笔记

    时间 程序的时间是本地时间 ,数据库中的时间是 ISO 标准时间 . ISO时间 + 8 小时 = 本地时间(北京时间 ) Java驱动会自动做转化. 语法 数组查询 数据查询使用 elemMatch ...

  6. 快速排序 O(nlogn)

    #include<bits/stdc++.h> using namespace std; int a[200],n; void q_sort(int l,int r){ if(l>r ...

  7. Junit4测试用例

    一.题目简介 测试一元一次方程的求解 二.源码的github链接 https://github.com/liujing1994/test1 三.所设计的模块测试用例.测试结果截图   一元一次方程测试 ...

  8. 使用git命令创建分支到团队项目

    背景 在我们的团队中,我作为管理者,创建了一个叫HelloWorld的项目,大家各自在本地进行开发,将自己的工作贡献到我们的团队项目中.为了便于审核,我希望大家先将自己的贡献先放在属于自己的一个分支上 ...

  9. 防止xss攻击。

    function htmlEscape(text){ return text.replace(/[<>&\"=]/g,function(match,pos,origina ...

  10. 面象对象设计原则之四:接口隔离原则(The Interface Segregation Principle,ISP)

    接口隔离原则定义如下: 接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口. 根 ...