嘟嘟嘟




如果没有限制,而且必须选\(m\)件的话,就是隔板法\(C_{n + m - 1} ^ {m - 1}\)了。现在要选至多\(m\)件,那么就相当于新增一个板儿,分出的新的盒子表示“多出来的”,也就是说前\(m\)个盒子是选出来的宝具,这样就能满足至多\(m\)个的限制了,即\(C_{n + m} ^ {m}\)。

从公式这一角度来说,就是\(\sum _ {i = 0} ^ {n} C_ {i + m - 1} ^ {m - 1} = C_{n + m} ^ {m}\),至于证明,在我的另一篇博客上有,题解:bzoj4403 序列统计。




现在我们加上了\(T\)这个限制。我一直在想,\(T\)这么小,显然可以\(2 ^ T\)暴力枚举,但那又有啥用咧?

后来某大佬的题解告诉我,你怎么就想不到容斥啊?

好像有道理,答案等于至少0个神器超过限制的方案数 - 至少1个神器超过限制方案数 + 至少3个超过限制 - ……而对于每一个方案数,我们先强制让这些神器选\(B_i + 1\)个,然后剩下的随便选,就是\(C_{n + m - \sum(B_i + 1)} ^ {m - \sum (B_i + 1)} = C_{n + m - \sum(B_i + 1)} ^ {n}\)。




最后因为模数小,上lucas。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<assert.h>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e6 + 5;
In ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
In void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
In void MYFILE()
{
#ifndef mrclr
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
} int n, T, m, mod, b[20]; ll fac[maxn], inv[maxn];
In ll inc(ll a, ll b) {return a + b < mod ? a + b : a + b - mod;}
In ll C(int n, int m)
{
if(m > n) return 0;
return fac[n] * inv[n - m] % mod * inv[m] % mod;
}
In ll lucas(int n, int m)
{
ll ret = 1;
for(; m; n /= mod, m /= mod)
ret = ret * C(n % mod, m % mod) % mod;
return ret;
}
In ll quickpow(ll a, ll b)
{
ll ret = 1;
for(; b; b >>= 1, a = a * a % mod)
if(b & 1) ret = ret * a % mod;
return ret;
} In void init()
{
fac[0] = inv[0] = 1;
for(int i = 1; i < mod; ++i) fac[i] = fac[i - 1] * i % mod;
inv[mod - 1] = quickpow(fac[mod - 1], mod - 2);
for(int i = mod - 2; i; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
} int main()
{
//MYFILE();
n = read(), T = read(), m = read(), mod = read();
for(int i = 1; i <= T; ++i) b[i] = read();
init();
ll ans = 0;
for(int i = 0; i < (1 << T); ++i)
{
int cnt = 0, tp = m;
for(int j = 1; j <= T; ++j)
if((i >> (j - 1)) & 1) ++cnt, tp -= b[j] + 1;
ans = inc(ans, (cnt & 1) ? mod - lucas(n + tp, n) : lucas(n + tp, n));
}
write(ans), enter;
return 0;
}

[BJWC2008]王之财宝的更多相关文章

  1. Luogu4640 BJWC2008 王之财宝 容斥、Lucas

    传送门 题意:有$N$种物品,其中$T$个物品有限定数量$B_i$,其他则没有限定.问从中取出不超过$M$个物品的方案数,对质数$P$取模.$N,M \leq 10^9 , T \leq 15 , P ...

  2. 洛谷P4640 王之财宝 [BJWC2008] 数论

    正解:容斥+Lucas+组合数学 解题报告: 传送门! 和上一篇题解的题差不多,,,双倍经验趴大概算 还是说下还是有点儿区别的来着$QwQ$ 两个小差别分别港下$QwQ$ 首先有$m-n$件是无穷个的 ...

  3. P4640-[BJWC2008]王之财宝【OGF,Lucas定理】

    正题 题目链接:https://www.luogu.com.cn/problem/P4640 题目大意 \(n\)种物品,其中\(t\)种物品是有个数限制的,第\(i\)种限制为\(b_i\),求选出 ...

  4. [SDOI2010]所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  5. 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  6. [LuoguP2403][SDOI2010]所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  7. 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)

    「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...

  8. BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】

    Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...

  9. 洛谷 2403 [SDOI2010] 所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐, ...

随机推荐

  1. sonar+Jenkins 构建代码质量自动化分析平台

    1.Sonar 介绍 Sonar 是一个用于管理代码质量的开源工具,可以分析代码中的bug和漏洞以及Code Smells,支持20多种编程语言的检测,如java,c/c++,python,php等语 ...

  2. Centos6 yum安装nginx

    1.Centos6系统库中默认是没有nginx的rpn包的,所以我们需要先更新下rpm依赖库 (1):使用yum安装nginx,安装nginx库 rpm -Uvh http://nginx.org/p ...

  3. C# DateTime Subtract

    DateTime start = DateTime.Now.AddDays(-20); DateTime end = DateTime.Now; TimeSpan ts = end.Subtract( ...

  4. Android监听EditText输入字符串,删除指定的字符

    alert_ed = (EditText) a.findViewById(R.id.alert_ed_queue_num); alert_ed.addTextChangedListener(mText ...

  5. 笔记: ASP.NET Core视图组件

    视图组件 asp.net core mvc 提供了部分视图的新替代品:视图组件. 视图组件与分布视图的主要区别在于视图组件与控制器不相关.可使用在独立于单个控制器的场景,如:菜单导航.侧边栏.分页栏等 ...

  6. Google Drive 和 Dropbox 同步同一个文件夹目录

     Dropbox 也是非常棒的同步工具,例如先进的增量上传或者更开放的 API 等.可是为什么不曾想过把 Google Drive 和 Dropbox 同时使用呢,我是说,让这两者同时云同步同一个文件 ...

  7. 听课笔记--DP--最大子矩阵和

    最大子矩阵问题 给定一个n*n(0<n<=120)的矩阵, 矩阵内元素有正有负, 请找到此矩阵的内部元素和最大的子矩阵 样例输入: 4 0 -2 -7  0  9  2 -6  2  -4 ...

  8. 分享一张理解数据库inner join,left join,right join,full join的图

  9. vue slot的使用(transform动画)

    slot的说明就看vue的官方文档  但是有点模糊 理解: 是对组件的扩展,通过slot插槽向组件内部指定位置传递内容,通过slot可以父子传参:   解决什么问题:正常情况下,<Child&g ...

  10. flask 中的ORM ( 二 )

    1 关系映射 1 多对多 1 什么是多对多 A表中的一条数据可以与B表中任意多条数据相关联 B表中的一条数据可以与A表中任意多条数据相关联 2 实现 在数据库中使用第三张表(关联表) 在编程语言中,可 ...