【题解】CF#896 D-Nephren Runs a Cinema
容易发现这些 vip 用户并没什么用,所以考虑枚举手持50元与100元的人共有多少个。设手持50元的人 \(a\) 个,手持100元的人 \(a - k\) 个,那么一共是 \(2*a - k\) 个人,最后手上会剩余 \(k\) 张50元钞票。用卡特兰数计算得到在这种情况下的方案数就是:
\((\binom{2 * a - k}{a} - \binom{2 * a - k}{a + 1}) * \binom{n}{2 * a - k}\)
其中 \(l <= k <= r, 1 <= 2 * a - k <= n\)。
把组合数分开计算,得到答案其实是两部分的和:
\((\binom{2 * a - k}{a} * \binom{n}{2 * a - k}\)
与 \(-\binom{2 * a - k}{a + 1} * \binom{n}{ 2 * a - k}\)
注意到这两个式子均可以化简\(\binom{n}{m} * \binom{m}{r} = \binom{n}{r} * \binom{n - m}{m - r}\),
得到:
\(ans = \binom{n}{a}\binom{n - a}{a - k} - \binom{n}{a + 1} * \binom{n - a - 1}{a - k - 1}\)
分开计算两个部分的和,发现上部分是在计算 \(\sum \binom{n}{a}\binom{n - a}{a - k} (a\in [1, n], k \in [l, r])\)
而下部分则是在计算 \(\sum \binom{n}{a}\binom{n - a}{a - k - 2} (a\in [2, n + 1], k \in [l, r])\)
把中间同样的部分约去即可得到一个 \(O(n)\) 的式子,每一步需求解一个组合数。
然后问题是怎样求出 \(n\) 个对合数取模的组合数?常见思路利用扩展卢卡斯已经不可行,但鉴于此题 \(n\) 比较小,我们可以暴力拆分组合数中的阶乘数。对于与模数互质的部分利用欧拉定理求出逆元,照常处理;不互质的则计算上下约去了多少个质因子后暴力累乘贡献。
#include <bits/stdc++.h>
using namespace std;
#define maxn 200000
#define CNST 30
#define int long long
int n, P, L, R, ans, cnt, fac[maxn], finv[maxn];
int tot, a[maxn], num[maxn][CNST]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void Up(int &x, int y) { x = (x + y) % P; if(x < ) x += P; }
int Qpow(int x, int timer, int P)
{
int base = ;
for(; timer; timer >>= , x = x * x % P)
if(timer & ) base = base * x % P;
return base;
} void Pre(int n) {
int x = P, phi = P; fac[] = finv[] = ;
for(int i = ; i * i <= x; i ++)
if(x % i) continue;
else {
phi = phi / i * (i - ); a[++ cnt] = i;
while(!(x % i)) x /= i;
}
if(x > ) phi = phi / x * (x - ), a[++ cnt] = x; for(int i = ; i <= n; i ++) {
int t = i;
for(int j = ; j <= cnt; j ++) {
num[i][j] = num[i - ][j];
while(!(t % a[j])) t /= a[j], num[i][j] ++;
}
fac[i] = fac[i - ] * t % P;
finv[i] = Qpow(fac[i], phi - , P);
}
} int Get_C(int n, int m)
{
int ret = fac[n] * finv[m] % P * finv[n - m] % P, x, y;
if(n < || m < || n < m) return ;
for(int i = ; i <= cnt; i ++)
{
if(a[i] > n) break;
int cnt = num[n][i] - num[m][i] - num[n - m][i];
ret = ret * Qpow(a[i], cnt, P) % P;
}
return ret;
} signed main()
{
n = read(), P = read(), L = read(), R = read();
Pre(n + );
for(int i = ; i <= n; i ++)
{
if(L > i || R < ) continue;
int l = max(L, 0LL), r = min(i, R), t = Get_C(n, i);
Up(ans, P - t * Get_C(n - i + , i - r - ) % P);
Up(ans, t * Get_C(n - i + , i - l) % P);
}
printf("%I64d\n", ans);
return ;
}
【题解】CF#896 D-Nephren Runs a Cinema的更多相关文章
- 【CF896D】Nephren Runs a Cinema 卡特兰数+组合数+CRT
[CF896D]Nephren Runs a Cinema 题意:一个序列中有n格数,每个数可能是0,1,-1,如果一个序列的所有前缀和都>=0且总和$\in [L,R]$,那么我们称这个序列是 ...
- CF896D Nephren Runs a Cinema
CF896D Nephren Runs a Cinema 题意 售票员最开始没有纸币,每次来一个顾客可以给她一张.拿走她一张或不操作.求出不出现中途没钱给的情况 \(n\) 名顾客后剩余钱数在 \(l ...
- CodeForces - 896D :Nephren Runs a Cinema(卡特兰数&组合数学---比较综合的一道题)
Lakhesh loves to make movies, so Nephren helps her run a cinema. We may call it No. 68 Cinema. Howev ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T5(思维)
还是dfs? 好像自己写的有锅 过不去 看了题解修改了才过qwq #include <cstdio> #include <algorithm> #include <cst ...
- 竞赛题解 - [CF 1080D]Olya and magical square
Olya and magical square - 竞赛题解 借鉴了一下神犇tly的博客QwQ(还是打一下广告) 终于弄懂了 Codeforces 传送门 『题目』(直接上翻译了) 给一个边长为 \( ...
- [题解] [CF 1250J] The Parade
题面 题目大意: 给定一个 \(n\) , 所有军人的数量均在 \([1, n]\) 给定 \(a_i\) 代表高度为 \(i\) 的军人的个数 你要将这些军人分成 \(k\) 行, 满足下面两个条件 ...
- 题解 CF 1372 B
题目 传送门 题意 给出 \(n\),输出 \(a\) ,\(b\) (\(0 < a \leq b < n\)),使\(a+b=n\)且 \(\operatorname{lcm}(a,b ...
- 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T4(模拟)
随便模拟下就过了qwq 然后忘了特判WA了QwQ #include <cstdio> #include <algorithm> #include <cstring> ...
随机推荐
- docker-compose 部署 EFK
信息: Docker版本($ docker --version):Docker版本18.06.1-ce,版本e68fc7a 系统信息($ cat /etc/centos-release):CentOS ...
- WebGL2系列之实例数组(Instanced Arrays)
实例化数组 实例化是一种只调用一次渲染函数却能绘制出很多物体的技术,它节省渲染一个物体时从CPU到GPU的通信时间.实例数组是这样的一个对象,使用它,可以把原来的的uniform变量转换成attrib ...
- java基础---JDK、JRE、JVM的区别和联系
当我们学习java语言时,首先需要安装到我们电脑上的就是jdk.jdk是java语言的开发环境,只有安装了jdk,我们才能使用java语言开发程序. JDK=JRE+开发工具包 JRE=JVM+核心类 ...
- gitlab+jenkins持续集成(三)
构建: 需要将jenkins服务器上 jenkins用户的公钥发送给 目标服务器的gs用户,使得在jenkins上能用gs免密登录目标服务器 复制密钥到目标机器上(需要登录到的机器) ssh-co ...
- Linux 磁盘与文件系统(EXT2)简介
Linux 中,一切(或几乎一切)都是文件. 一.Linux 磁盘分区与文件系统 1.1 磁盘分区 磁盘的分区主要分为主分区和扩展分区 1)主分区:总共最多只能有四个主分区: 2)扩展分区:只能有一个 ...
- centos6.9+lnmp1.5环境部署swoole记录
hiredis下载地址:https://github.com/redis/hiredis/releasesunzip hiredis-v0.13.3.zipmake -jsudo make insta ...
- [转载]GBK 汉字内码扩展规范编码表(1.0 版)
编码表源地址:http://ff.163.com/newflyff/gbk-list/ 编码在线查询:http://www.qqxiuzi.cn/bianma/zifuji.php GBK 汉字内码扩 ...
- Erlang数据类型的表示和实现(1)——数据类型回顾
本文介绍 Erlang 语言中使用的各种数据类型以及这些数据类型在 Erlang 虚拟机内部的表示和实现.了解数据类型的实现可以帮助大家在实际开发过程中正确选择数据类型,并且可以更好更高效地操作这些数 ...
- 苹果针对on sale 的APP发的问题邮件
2017年3月8日 上午8:07 发件人 Apple Dear Developer, Your app, extension, and/or linked framework appears to c ...
- 忘记本地MySQL数据库密码的解决方案。
忘记本地MySQL数据库密码,解决方案,分以下10个步骤: 参考链接: https://blog.csdn.net/weidong_y/article/details ...