【BZOJ2142】礼物

Description

小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
【样例说明】
下面是对样例1的说明。
以“/”分割,“/”前后分别表示送给第一个人和第二个人的礼物编号。12种方案详情如下:
1/23 1/24 1/34
2/13 2/14 2/34
3/12 3/14 3/24
4/12 4/13 4/23
【数据规模和约定】
设P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数。
对于100%的数据,1≤n≤109,1≤m≤5,1≤pi^ci≤10^5。

题解:答案很简单,$ans=C_{tot}^{w1}C_{tot-w1}^{w2}C_{tot-w1-w2}^{w3}...$。

但是问题来了,首先模数既不是质数,也不是若干独立质数的乘积,而是质数的幂次之积。我们还是先用中国剩余定理,将模数变成质数的幂次,但此时普通的lucas定理无法使用,我们怎么求组合数呢?

我们考虑将组合数变成阶乘相除的形式,再将分子和分母中的阶乘都化成$a\times p^b$的形式(a对$p^c$取模),最后答案的a等于分子的a乘上分母的a的逆元,答案的b等于分子的b-分母的b。那么我们考虑如何将一个数的阶乘化成$a\times p^b$的形式。

以$p=5,p^c=25$为例,然后将n的阶乘中5的倍数都提出来考虑:

$n!=(1\times2\times3\times4\times6\times7\times...)\times5^{\lfloor\frac n 5\rfloor}\times(\lfloor\frac n 5\rfloor)!$

那么如何处理前面的那坨东西呢?我们可以先预处理出$1...24$的阶乘(不计算p的倍数),即为jc,然后前面的那堆东西就变成了$jc[24]^{\lfloor \frac n {25}\rfloor}\times jc[n\%25]$。

对于后面的那个阶乘,我们可以递归处理下去,每次n的大小会除以p,所以复杂度是可以接受的~

最后用CRT合并,求逆元时用exgcd即可,注意判Impossible的情况。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=100010;
ll n,m,num,P,PP,PC,Pri,ans;
ll w[10],jc[maxn];
inline ll pm(ll x,ll y)
{
ll ret=1;
while(y)
{
if(y&1) ret=ret*x%PP;
x=x*x%PP,y>>=1;
}
return ret;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1,y=0;
return ;
}
exgcd(b,a%b,x,y);
ll t=x;
x=y,y=t-a/b*x;
}
inline ll ine(ll a)
{
ll x,y;
exgcd(a,PP,x,y);
return x;
}
struct node
{
ll x,y;
node() {x=1,y=0;}
node(ll a,ll b) {x=a,y=b;}
node operator + (const node &a) const {return node(x*a.x%PP,y+a.y);}
node operator * (const ll &a) const {return node(pm(x,a),y*a);}
node operator - (const node &a) const {return node(x*(ine(a.x)+PP)%PP,y-a.y);}
};
inline node getjc(ll x)
{
if(x<P) return node(jc[x],0);
return node(pm(jc[PP-1],x/PP)*jc[x%PP]%PP,x/P)+getjc(x/P);
}
inline ll solve()
{
ll i,sum=n;
for(jc[0]=1,i=1;i<PP;i++)
{
jc[i]=jc[i-1];
if(i%P) jc[i]=jc[i]*i%PP;
}
node a,b;
for(i=1;i<=m;i++) b=b+getjc(w[i]),sum-=w[i];
a=getjc(n),b=b+getjc(sum);
a=a-b;
return a.x*pm(P,a.y);
}
inline ll CRT()
{
ll i,t=Pri;
for(i=2;i*i<=t;i++)
{
if(t%i==0)
{
P=i,PP=1,PC=0;
while(t%i==0) t/=i,PP*=i,PC++;
ans=(ans+ine(Pri/PP)*solve()*(Pri/PP))%Pri;
}
}
if(t!=1)
{
P=PP=t,PC=1;
ans=(ans+ine(Pri/PP)*solve()*(Pri/PP))%Pri;
}
return (ans+Pri)%Pri;
}
int main()
{
scanf("%lld%lld%lld",&Pri,&n,&m);
ll tmp=0;
for(ll i=1;i<=m;i++) scanf("%lld",&w[i]),tmp+=w[i];
if(tmp>n)
{
printf("Impossible");
return 0;
}
printf("%lld",CRT());
return 0;
}

【BZOJ2142】礼物 组合数+CRT的更多相关文章

  1. BZOJ 2142 礼物 组合数学 CRT 中国剩余定理

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

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

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

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

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

  4. BZOJ2142: 礼物(拓展lucas)

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

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

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

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

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

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

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

  8. HZOI20190722 B visit 组合数+CRT合并

    题目:https://www.cnblogs.com/Juve/articles/11226266.html solution: 30%:dp 设dp[k][i][j]表示经过k时间,在(i,j)的方 ...

  9. bzoj2142: 礼物

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

随机推荐

  1. Web API(二):Web API概述

    一.什么是API API(Application Programming Interface)即应用程序编程接口,是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能 ...

  2. apt-get强制使用Ipv4

    sudo apt-get -o Acquire::ForceIPv4=true update 永久解决办法: 创建文件 /etc/apt/apt.conf.d/99force-ipv4 加入代码: A ...

  3. am335x LCD参数更改

    /******************************************************************** * am335x LCD参数更改 * * 本文记录am335 ...

  4. Spring 4 官方文档学习(十一)Web MVC 框架之themes

    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-themeresolver ...

  5. android2.2应用开发之IccCard(sim卡或USIM卡)(转至 http://www.2cto.com/kf/201306/223784.html)

    如果要做android通讯录的联系人的机卡混排显示,由于手机卡类型的不同,导致手机卡存储容量以及可以存储信息不同,就要涉及到android去读Icc卡的信息. 一般的sim卡只能存储姓名跟一个电话号码 ...

  6. UVA 1371 - Period(DP)

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=4117&mo ...

  7. JBPM——工作流概念

    一.概念          工作流(Workflow),就是"业务过程的部分或总体在计算机应用环境下的自己主动化",它主要解决的是"使在多个參与者之间依照某种提前定义的规 ...

  8. php判断来访者是否是搜索引擎的蜘蛛

    我们可以通过HTTP_USER_AGENT来判断是否是蜘蛛,搜索引擎的蜘蛛都有自己的独特标志,下面列取了一部分. function is_crawler() { $userAgent = strtol ...

  9. Nginx伪静态配置和常用Rewrite伪静态规则集锦

    伪静态是一种可以把文件后缀改成任何可能的一种方法,如果我想把php文件伪静态成html文件,这种相当简单的,下面我来介绍nginx 伪静态配置方法 nginx里使用伪静态是直接在nginx.conf ...

  10. 扁平化你的Qt应用程序

    什么是扁平化 这里的扁平化指的是交互设计方面的一种风格. 扁平化是随着极简注意的风潮流行起来的,这个概念最核心的地方就是放弃一切装饰效果,诸如阴影.透视,纹理,渐变等等能做出3D效果的元素一概不用.全 ...