【BZOJ 1272】 1272: [BeiJingWc2008]Gate Of Babylon (容斥原理+卢卡斯定理)

1272: [BeiJingWc2008]Gate Of Babylon

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 254  Solved: 120

Description

Input

Output

Sample Input

Sample Output

12

HINT

Source

【分析】

  T很小,跟以前的某一题很像啊,就是容斥。

  枚举不符合的(超过限制的),2^t,然后就是算 n种无限多的东东中选m个。

  经典的组合数题,$C_{n+m-1}{n-1}$。不过是不超过m个,就是求和。

  $C_{n-1}{n-1}+C_{n}{n-1}+...C{n+m-1}{n-1}$

  这个也很经典啦,【又是数学卷子上的熟悉背影呵呵】,$C_{i}{j}=C_{i-1}{j-1}+C_{i-1}{j}$

  在前面加一个$C_{n-1}{n}$,最后化成$C_{n}{n+m}$

  这题到了10^9,预处理幂也没用。于是上卢卡斯定理。

【有傻逼卡评测现在并没有交】

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 100010
 8
 9 int w[20],Mod;
10 int inv[Maxn],pw[Maxn];
11
12 void init()
13 {
14     pw[0]=1;for(int i=1;i<=Mod;i++) pw[i]=1LL*pw[i-1]*i%Mod;
15     inv[1]=1;for(int i=2;i<=Mod;i++) inv[i]=1LL*(Mod-Mod/i)*inv[Mod%i]%Mod;
16     inv[0]=1;for(int i=1;i<=Mod;i++) inv[i]=1LL*inv[i-1]*inv[i]%Mod;
17 }
18
19 int get_c(int n,int m)
20 {
21     if(n<m) return 0;
22     return 1LL*pw[n]*inv[m]%Mod*inv[n-m]%Mod;
23 }
24
25 int lucas(int n,int m)
26 {
27     if(n<m) return 0;
28     int ans=1;
29     while(n&&m)
30     {
31         ans=1LL*get_c(n%Mod,m%Mod)*ans%Mod;
32         n/=Mod;m/=Mod;
33     }
34     return ans;
35 }
36
37 int main()
38 {
39     int n,t,m;
40     scanf("%d%d%d%d",&n,&t,&m,&Mod);
41
42     init();
43
44     for(int i=1;i<=t;i++) scanf("%d",&w[i]);
45     int ans=0;
46     for(int i=0;i<=(1<<t)-1;i++)
47     {
48         int mm=m,ll=0;
49         for(int j=1;j<=t;j++) if(i&(1<<j-1)) mm-=w[j]+1,ll++;
50         if(ll&1) ans-=lucas(n+mm,n);
51         else ans+=lucas(n+mm,n);
52         ans=(ans%Mod+Mod)%Mod;
53     }
54     printf("%d\n",ans);
55     return 0;
56 }



记录:LUCAS定理

For non-negative integers m and n and a prime p, the following congruence relation holds:

where

and

are the base p expansions of m and n respectively.

(2)证明:

n=(ak...a2,a1,a0)

p = (ak...a2,a1)

p*p + a0 =  [n/p]*p+a0,m=[m/p]*p+b0

其次,我们知道,对任意质数p有(1+x)^p=1+(x^p)(mod p) 。

我们只要证明这个式子:C(n,m)=C([n/p],[m/p]) * C(a0,b0)(mod p),那么就可以用归纳法证明整个定理。对于模p而言,我们有下面的式子成立:

上式左右两边的x的某项x^m(m<=n)的系数对模p同余。其中左边的x^m的系数是 C(n,m)。 而由于a0和b0都小于p,因此右边的x^m 一定是由 x^([m/p]*p) 和 x^b0 (即i=[m/p] , j=b0 ) 相乘而得 因此有:C(n,m)=C([n/p],[m/p]) * C(a0,b0)  (mod p)。

3、当p不是质数,还是中国剩余定理合并的套路。【不过有些特殊

拓展应用:上面的p是素数,那么不是素数怎么办呢?若不是素数,将p分解质因数,将C(n,m)分别按照(1)中的方法求对p的质因数的模,然后用中国剩余定理合并。比如计算C(10,3)%14。C(10,3)=120,14有两个质因数2和7,120%2=0,120%7=1,这样用(2,0)(7,1)找到最小的正整数8即是答案,即C(10,3)%14=8。注意,这里只适用于p分解完质因数后每个质因数只出现一次,例如12=2*2*3就不行,因为2出现了两次。若p分解完质因数后,含有某个质因数出现多次,比如C(10,3)%98,其中98=2*7*7,此时就要把7*7看做一个数,即:120%2=0,120%49=22,用(2,0)(49,22)和中国剩余定理得到答案22,即C(10,3)%98=22。此时,你又会有疑问,C(10,3)%49不也是模一个非素数吗?此时不同的是这个非素数不是一般的非素数,而是某个素数的某次方。下面(4)介绍如何计算C(n,m)%p^t(t>=2,p为素数)。

4、计算C(n,m)%p^t。

我们知道,C(n,m)=n!/m!/(n-m)!,若我们可以计算出n!%p^t,我们就能计算出m!%p^t以及(n-m)!%p^t。我们不妨设x=n!%p^t,y=m!%p^t,z=(n-m)!%p^t,那么答案就是x*reverse(y,p^t)*reverse(z,p^t)(reverse(a,b)计算a对b的乘法逆元)。那么下面问题就转化成如何计算n!%p^t。比如p=3,t=2,n=19,

n!=1*2*3*4*5*6*7*8* ……*19

=[1*2*4*5*7*8*… *16*17*19]*(3*6*9*12*15*18)

=[1*2*4*5*7*8*… *16*17*19]*3^6(1*2*3*4*5*6)

然后发现后面的是(n/p)!,于是递归即可。前半部分是以p^t为周期的[1*2*4*5*7*8]=[10*11*13*14*16*17](mod 9)。下面是孤立的19,可以知道孤立出来的长度不超过 p^t,于是暴力即可。那么最后剩下的3^6啊这些数怎么办呢?我们只要计算出n!,m!,(n-m)!里含有多少个p(不妨设a,b,c),那么a-b-c就是C(n,m)中p的个数,直接算一下就行。

转自:http://blog.csdn.net/yuyanggo/article/details/47380777

【还挺好打】

2017-04-16 14:13:29

时间: 2024-11-14 20:58:23

【BZOJ 1272】 1272: [BeiJingWc2008]Gate Of Babylon (容斥原理+卢卡斯定理)的相关文章

BZOJ1272: [BeiJingWc2008]Gate Of Babylon

题解: 多重集合的组合数?还是0-m?有些元素有个数限制? 多重集合的组合数可以插板法,0-m直接利用组合数的公式一遍求出来,个数限制注意到只有15个,那我们就暴力容斥了 AC了真舒畅.. 注意开long long 1 ll n,m,a[20],k,p,ans,fac[maxn],inv[maxn]; 2 inline ll c(ll n,ll m) 3 { 4 if(n<m)return 0; 5 if(n<p&&m<p)return fac[n]*inv[m]%p*i

bzoj 1272: [BeiJingWc2008]Gate Of Babylon

Description Solution 如果没有限制,答案就是 \(\sum_{i=0}^{m}C(n+i-1,i)\) 表示枚举每一次取的个数,且不超过 \(m\),方案数为可重组合 发现这个东西可以用杨辉三角合并,最终变成 \(C(n+m,m)\) 考虑有限制的情况,直接容斥一下即可,要使得一种物品不合法,我们先强制给他选 \(B_i+1\) 个,剩下的随意选 此题求组合数需要用 \(Lucas\) #include<bits/stdc++.h> using namespace std;

[BeiJingWc2008]Gate Of Babylon

<基尔伽美修>是人类历史上第一部英雄史诗,两河流域最杰出的文学作品之一.作品讲述了基尔伽美修一生的传奇故事.在动画Fate/staynight中,基尔伽美修与亚瑟王等传说中的英雄人物一起出现在了现实世界,展开了一场惊天地.泣鬼神的战斗一·在记载于12块泥板的史诗中,基尔伽美修与同伴安吉杜一起降伏了森林的守护者——神兽洪芭芭,成为地上最强的王者,同时将世间所有财宝收归手中.王之财宝(GateofBabylon)成为Fate中金皮卡(基尔伽美修的外号…)炫耀的资本……一天金皮卡突发奇想:如果从自己

bzoj 2111: [ZJOI2010]Perm 排列计数 (dp+卢卡斯定理)

bzoj 2111: [ZJOI2010]Perm 排列计数 1 ≤ N ≤ 10^6, P≤ 10^9 题意:求1~N的排列有多少种小根堆 1: #include<cstdio> 2: using namespace std; 3: const int N = 1e6+5; 4: typedef long long LL; 5: LL m, p, T, x, y, F[N]; 6: LL n, size[N<<1]; 7: LL f[N]; 8: LL inv(LL t, LL

【BZOJ】【1272】【BeiJingWC2008】Gate of Babylon

组合数学+容斥原理 Orz zyf-zyf 多重集组合数0.0还带个数限制?  ——>  <组合数学>第6章  6.2带重复的组合 组合数还要模P 0.0? ——> Lucas定理 啊……要算组合数啊……除以阶乘神马的太麻烦肿么办?还要模P……没关系~我们可以搞预处理啊= =预处理粗来[阶乘%P]和[阶乘在模P意义下的逆元] 1 void calc(){ 2 fac[0]=1; 3 F(i,1,P-1) fac[i]=fac[i-1]*i%P; 4 inv[P-1]=pow(fac

[BZOJ 1042][HAOI 2008]硬币购物(背包+容斥原理)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1042 刚开始搞容斥原理,还很有点吃力,我太弱了... 首先用被类似于背包的DP进行预处理,假设每种硬币个数无限制,求出f[i]=凑出面值i的方案总数. 但是实际上题目中每种硬币个数是有限制的,设四种硬币分别是a.b.c.d,则凑出面值S的方案中超出限制的方案数=a超出限制的方案数+b超出限制的方案数+c超出限制的方案数+d超出限制的方案数-a和b都超出限制的方案数-a和c都超出限

BZOJ 2393 Cirno的完美算数教室 容斥原理+DFS

警告:网上的题解都是误人子弟,看此篇题解之前请将脑海中对其它写于本题解之前的网上常见题解的印象全部消除之后方可阅读 此题的数据范围是10^9 但是10^10一样可以做 不影响 首先我们可以预处理出1~r以内所有只由2和9构成的⑨数 容易发现最多有1022个 但是其中有一些⑨数是另一些的倍数 比如说a是b的倍数 那么一个数如果是a的倍数那么就一定是b的倍数 我们只需要计算b即可 无需计算a 这里可以剪枝 不剪无妨 处理出不是另一个数的倍数的所有⑨数 最多应该有466个 求区间内这些数的倍数的数的数

【BZOJ 1271】 [BeiJingWc2008]秦腾与教学评估

1271: [BeiJingWc2008]秦腾与教学评估 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1184  Solved: 411 [Submit][Status] Description Input Output Sample Input Sample Output HINT 二分. 一道非常神奇的题.. 一定要注意到题目中说最多有一个地方是奇数个人!! 那么我们二分pos,如果0-pos的人数为偶数,那么ans一定在pos+1-r之

【BZOJ 1270】 [BeijingWc2008]雷涛的小猫

1270: [BeijingWc2008]雷涛的小猫 Time Limit: 50 Sec  Memory Limit: 162 MB Submit: 956  Solved: 457 [Submit][Status] Description   Input Output Sample Input Sample Output 8 HINT dp+优化. dp方程很好想,f[i][j]表示走到第i个柱子高度为j的地方的能获得的最多柿子. f[i][j]=max(f[i][j-1],f[k][j-d