[BZOJ2142]礼物(扩展Lucas)

2142: 礼物

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 2286  Solved: 1009
[Submit][Status][Discuss]

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
【样例说明】
下面是对样例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。

HINT

Source

[Submit][Status][Discuss]

数论大集合。

https://blog.csdn.net/clove_unique/article/details/54571216

答案显然$C_n^{n - w[1]}C_{n - w[1]}^{w[2]}C_{n - w[1] - w[2]}^{w[3]}......$,模数不互质成为难点。

扩展Lucas:将模数质因数分解,再用CRT合并。

问题就只剩下求$n!\%p_i^{k_i}$了。

首先由于不互质无法找到逆元,把$n!$中的$p_i$全部取出来:$ans=\lfloor\frac{n}{p}\rfloor+\lfloor\frac{n}{p^2} \rfloor+\lfloor\frac{n}{p^3}\rfloor+...$

然后考虑剩下部分怎么做,用$F(n,p_i,p_i^{k_i})$表示答案,$f(n,p_i,p_i^{k_i})$表示$\prod_{j=1,j\perp p_i}^{n}j(mod\ p_i^{k_i})$,则:

$F(n,p_i,p_i^{k_i})=\lfloor\frac{n}{p_i}\rfloor!\times p_i^{\lfloor\frac{n}{p_i}\rfloor}\times f(p_i^{k_i},p_i,p_i^{k_i})^{\lfloor\frac{n}{p_i^{k_i}}\rfloor}\times f(n\%p_i^{k_i})\%p_i^{k_i}$

递归处理即可,要用到exgcd。

复杂度好像是,$O(\sqrt{P}+m\log_{2}^{2}p_i^{k_i}\log{p_i})$不过肯定跑不满。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=l; i<=r; i++)
 4 typedef long long ll;
 5 using namespace std;
 6
 7 const int N=10010;
 8 ll mod,n,m,w[10],ans,x,y,Mod[N],st[N],r[N],num;
 9
10 ll ksm(ll a,ll b,ll p){
11     ll res;
12     for (res=1; b; a=a*a%p,b>>=1)
13         if (b&1) res=res*a%p;
14     return res;
15 }
16
17 ll exgcd(ll a,ll b,ll &x,ll &y){
18     ll d=a;
19     if (b) d=exgcd(b,a%b,y,x),y-=a/b*x; else x=1,y=0;
20     return d;
21 }
22
23 ll inv(ll t,ll p){ ll x,y; exgcd(t,p,x,y); return (x+p)%p; }
24
25 ll F(ll n,ll pi,ll pk){
26     if (!n) return 1;
27     ll ans=1;
28     rep(i,2,pk) if (i%pi) ans=ans*i%pk;
29     ans=ksm(ans,n/pk,pk);
30     rep(i,2,n%pk) if (i%pi) ans=ans*i%pk;
31     return ans*F(n/pi,pi,pk)%pk;
32 }
33
34 ll exlucas(ll n,ll m,ll pi,ll pk){
35     if (m>n) return 0;
36     ll a=F(n,pi,pk),b=F(m,pi,pk),c=F(n-m,pi,pk);
37     ll k=0;
38     for (ll i=n; i; i/=pi) k+=i/pi;
39     for (ll i=m; i; i/=pi) k-=i/pi;
40     for (ll i=n-m; i; i/=pi) k-=i/pi;
41     return a*inv(b,pk)%pk*inv(c,pk)%pk*ksm(pi,k,pk)%pk;
42 }
43
44 ll CRT(ll n,ll r[],ll m[]){
45     ll M=1,res=0,w;
46     rep(i,1,n) M*=m[i];
47     rep(i,1,n) w=M/m[i],res=(res+w*inv(w,m[i])*r[i])%M;
48     return (res+M)%M;
49 }
50
51 ll par(ll n,ll m[],ll st[]){
52     ll num=0;
53     for (ll i=2; i*i<=n; i++) if (n%i==0){
54         ll pk=1;
55         while (n%i==0) pk*=i,n/=i;
56         m[++num]=pk; st[num]=i;
57     }
58     if (n>1) m[++num]=n,st[num]=n;
59     return num;
60 }
61
62 ll excomb(ll n,ll m){
63     rep(i,1,num) r[i]=exlucas(n,m,st[i],Mod[i]);
64     return CRT(num,r,Mod);
65 }
66
67 int main(){
68     freopen("bzoj2142.in","r",stdin);
69     freopen("bzoj2142.out","w",stdout);
70     scanf("%lld\n",&mod); scanf("%lld%lld",&n,&m);
71     ll sum=0; rep(i,1,m) scanf("%lld",&w[i]),sum+=w[i];
72     if (n<sum){ puts("Impossible"); return 0; }
73     num=par(mod,Mod,st); ans=1;
74     rep(i,1,m) n-=w[i-1],ans=ans*excomb(n,w[i])%mod;
75     printf("%lld\n",ans);
76     return 0;
77 }

原文地址:https://www.cnblogs.com/HocRiser/p/8965222.html

时间: 2024-11-11 18:31:01

[BZOJ2142]礼物(扩展Lucas)的相关文章

BZOJ.2142.礼物(扩展Lucas)

题目链接 答案就是C(n,m1) * C(n-m1,m2) * C(n-m1-m2,m3)...(mod p) 使用扩展Lucas求解. 一个很简单的优化就是把pi,pi^ki次方存下来,因为每次分解p都是很慢的. 注意最后p不为1要把p再存下来!(质数) COGS 洛谷上的大神写得快到飞起啊QAQ 就这样吧 //836kb 288ms #include <cmath> #include <cstdio> typedef long long LL; int cnt,P[500],P

BZOJ2142 礼物 【扩展Lucas】

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

CF.100633J.Ceizenpok&#39;s formula(扩展Lucas)

题目链接 ->扩展Lucas //求C_n^k%m #include <cstdio> typedef long long LL; LL FP(LL x,LL k,LL p) { LL t=1ll; for(; k; k>>=1,x=x*x%p) if(k&1) t=t*x%p; return t; } void Exgcd(LL a,LL b,LL &x,LL &y) { if(!b) x=1ll, y=0ll; else Exgcd(b,a%b,y

BZOJ3129 [Sdoi2013]方程 【扩展Lucas】

题目 给定方程 X1+X2+. +Xn=M 我们对第l..N1个变量进行一些限制: Xl < = A X2 < = A2 Xn1 < = An1 我们对第n1 + 1..n1+n2个变量进行一些限制: Xn1+l > = An1+1 Xn1+2 > = An1+2 Xnl+n2 > = Anl+n2 求:在满足这些限制的前提下,该方程正整数解的个数. 答案可能很大,请输出对p取模后的答案,也即答案除以p的余数. 输入格式 输入含有多组数据,第一行两个正整数T,p.T表示

【模板】扩展Lucas随想

扩展Lucas解决的还是一个很Simple的问题: 求:$C_{n}^{m} \; mod \; p$. 其中$n,m$都会比较大,而$p$不是很大,而且不一定是质数. 扩展Lucas可以说和Lucas本身并没有什么关系,重要的是中国剩余定理.扩展Lucas这个算法中教会我们的除了算组合数,还有在模数不是质数的时候,往往可以用$CRT$来合并答案. 将原模数质因数分解:$P = \prod_{i = 1}^{m} p_{i}^{k_{i}}$. 列出$m$个同余方程,第$i$个形如:$C_{n}

bzoj2142 礼物

2142: 礼物 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 848  Solved: 357 [Submit][Status][Discuss] Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi.请你帮忙计算出送礼物的方案数(两个

扩展lucas定理

i64 POW(i64 a,i64 b,i64 mod) { i64 ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } i64 POW(i64 a,i64 b) { i64 ans=1; while(b) { if(b&1) ans=ans*a; a=a*a; b>>=1; } return ans; } i64 exGcd(i64 a,i64 b,i64 &

@bzoj - [email&#160;protected] 礼物

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多. 小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi. 请你帮忙计算出送礼物的方案数(两个方案被认

[bzoj1951] [Sdoi2010]古代猪文 费马小定理+Lucas定理+CRT

Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃