容易发现这些 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的更多相关文章

  1. 【CF896D】Nephren Runs a Cinema 卡特兰数+组合数+CRT

    [CF896D]Nephren Runs a Cinema 题意:一个序列中有n格数,每个数可能是0,1,-1,如果一个序列的所有前缀和都>=0且总和$\in [L,R]$,那么我们称这个序列是 ...

  2. CF896D Nephren Runs a Cinema

    CF896D Nephren Runs a Cinema 题意 售票员最开始没有纸币,每次来一个顾客可以给她一张.拿走她一张或不操作.求出不出现中途没钱给的情况 \(n\) 名顾客后剩余钱数在 \(l ...

  3. 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 ...

  4. 竞赛题解 - CF Round #524 Div.2

    CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...

  5. 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T5(思维)

    还是dfs? 好像自己写的有锅 过不去 看了题解修改了才过qwq #include <cstdio> #include <algorithm> #include <cst ...

  6. 竞赛题解 - [CF 1080D]Olya and magical square

    Olya and magical square - 竞赛题解 借鉴了一下神犇tly的博客QwQ(还是打一下广告) 终于弄懂了 Codeforces 传送门 『题目』(直接上翻译了) 给一个边长为 \( ...

  7. [题解] [CF 1250J] The Parade

    题面 题目大意: 给定一个 \(n\) , 所有军人的数量均在 \([1, n]\) 给定 \(a_i\) 代表高度为 \(i\) 的军人的个数 你要将这些军人分成 \(k\) 行, 满足下面两个条件 ...

  8. 题解 CF 1372 B

    题目 传送门 题意 给出 \(n\),输出 \(a\) ,\(b\) (\(0 < a \leq b < n\)),使\(a+b=n\)且 \(\operatorname{lcm}(a,b ...

  9. 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T4(模拟)

    随便模拟下就过了qwq 然后忘了特判WA了QwQ #include <cstdio> #include <algorithm> #include <cstring> ...

随机推荐

  1. Vue2.0原理-指令

    指令是 模板解析 的续章,本文会尝试从源码的角度来理解 指令 是如何被提取和应用的. 指令的提取 指令的提取过程是在parse阶段进行的,在 parseHTML 方法中,会解析字符串模板为如下的单个a ...

  2. POJ2251-Dungeon Master(3维BFS)

    You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of un ...

  3. 文件的上传和下载--SpringMVC

    文件的上传和下载是项目开发中最常用的功能,例如图片的上传和下载.邮件附件的上传和下载等. 接下来,将对Spring MVC环境中文件的上传和下载进行详细的讲解. 一.文件上传 多数文件上传都是通过表单 ...

  4. NIKTO介绍及使用方法

    1.    NIKTO:perl语言开发的开源WEB安全扫描器:识别网站软件版本:搜索存在安全隐患的文件:检查服务器配置漏洞:检查WEB Application层面的安全隐患:避免404误判(原因:很 ...

  5. kubernetes高可用设计-CA,etcd

    环境准备: master01:192.168.150.128 master02:192.168.150.130 master03:192.168.150.131 node01:192.168.150. ...

  6. React Native移动开发实战-2-如何调试React Native项目

    在实际开发中,还有一个影响开发效率的重要因素:调试. 在1.4.3节中已经介绍了Enable Live Debugger的使用.本节来介绍另一个非常重要的调试选项:Debug JSRemotely选项 ...

  7. python3 拼接字符串的7种方法

    1.直接通过(+)操作符拼接 1 2 >>> 'Hello' + ' ' + 'World' + '!' 'Hello World!' 使用这种方式进行字符串连接的操作效率低下,因为 ...

  8. kafka consumer demo

    kafka消费者demo pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  9. 局域网传输-LED灯搭建局域网:数据传输可达每秒3Gb

    一 : LED灯搭建局域网:数据传输可达每秒3Gb 我们之前介绍了利用可见光通讯技术,通过LED灯光实现精准室内定位的例子.实际上,这种灯泡和技术的用途不止于此,比如,它还能进行无线网络传输. 最近, ...

  10. 解决maven update project 后项目jdk变成1.5

    http://blog.csdn.net/jay_1989/article/details/52687934