【CF896D】Nephren Runs a Cinema 卡特兰数+组合数+CRT
【CF896D】Nephren Runs a Cinema
题意:一个序列中有n格数,每个数可能是0,1,-1,如果一个序列的所有前缀和都>=0且总和$\in [L,R]$,那么我们称这个序列是合法的。求合法序列的个数%P。
n,L,R<=100000,P<=2*10^9
题解:先不考虑0的数,那么总数显然就是卡特兰数的变形。我们将卡特兰数转换成在二维平面上,从(0,0)走到(a,b),且不越过直线x=y的方案数。因为每个越过x=y的方案都可以转化成从(-1,1)走到(a,b)的方案,所以总方案数就是$C_{a+b}^b-C_{a+b}^{b-1}$。如果序列的总和为j,那么令a=(n+j)/2,b=(n-j)/2即可。如果我们要对$j\in [L,R]$的所有方案数求和,那么答案就变成$C_n^{\lfloor{n-L\over 2}\rfloor}-C_n^{\lceil{n-R\over r}\rceil}$。
那如果我们考虑0呢?如果i个人是0,那么总方案数*$C_n^i$即可。
但是问题来了,模数不是质数怎么办?还记得礼物那题吗?我们先将模数拆成$\prod p_i^{c_i}$的形式,然后对于$p_i^{c_i}$分开计算。我们希望把阶乘表示成$a*p^b$的形式,这样就可以支持除法了(a可以求逆元搞定,b可以直接相减),具体如何实现?我们将n!中p的倍数都拿出来,比如p=5,那么n!可以表示成
$n!=(1\times2\times3\times4\times6\times7\times8\times9\times11...)\times5^{\lfloor{n\over 5}\rfloor}\times(\lfloor{n\over 5}\rfloor)!$
对于前面那些东西我们可以预处理,后面那个阶乘我们递归算下去即可(也可以递推求出)。
最后用中国剩余定理合并即可。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=100010;
ll n,L,R,cnt;
ll Pri,P,PP,phi,ans;
ll cp[10],cpp[10];
inline ll pm(ll x,ll y,ll z)
{
ll ret=1;
while(y)
{
if(y&1) ret=ret*x%z;
x=x*x%z,y>>=1;
}
return ret;
}
struct node
{
ll x,y;
node() {x=y=0;}
node(ll a,ll b) {x=a,y=b;}
node operator + (const node &a) {return node(x+a.x,y*a.y%PP);}
node operator * (const int a) {return node(x*a,pm(y,a,PP));}
}jc[maxn],f[maxn];
inline ll c(ll a,ll b)
{
if(b<0) return 0;
node x=f[a],y=f[a-b]+f[b];
return pm(P,x.x-y.x,PP)*x.y%PP*pm(y.y,PP/P*(P-1)-1,PP)%PP;
}
inline ll solve()
{
ll ret=0,i;
memset(jc,0,sizeof(jc)),memset(f,0,sizeof(f));
jc[0]=node(0,1);
for(i=1;i<=min(n,PP-1);i++)
{
jc[i]=jc[i-1];
if(i%P) jc[i].y=jc[i].y*i%PP;
}
for(i=0;i<=min(n,P-1);i++) f[i]=jc[i];
for(;i<=n;i++) f[i]=(n>=PP?(jc[PP-1]*(i/PP)):node(0,1))+jc[i%PP]+node(i/P,1)+f[i/P];
for(i=L;i<=n;i++) ret=(ret+c(n,i)*(c(i,i-(i+L+1)/2)-c(i,i-(i+R)/2-1)+PP))%PP;
return ret;
}
int main()
{
scanf("%I64d%I64d%I64d%I64d",&n,&Pri,&L,&R);
int i;
ll tmp=Pri;
phi=1;
for(i=2;i*i<=tmp;i++)
{
if(tmp%i==0)
{
tmp/=i,phi*=i-1;
cp[++cnt]=i,cpp[cnt]=i;
while(tmp%i==0) tmp/=i,phi*=i,cpp[cnt]*=i;
}
}
if(tmp!=1) phi*=(tmp-1),cp[++cnt]=tmp,cpp[cnt]=tmp;
for(i=1;i<=cnt;i++)
{
P=cp[i],PP=cpp[i];
ans=(ans+(Pri/PP)*pm(Pri/PP,phi-1,Pri)%Pri*solve())%Pri;
}
printf("%I64d",ans);
return 0;
}
【CF896D】Nephren Runs a Cinema 卡特兰数+组合数+CRT的更多相关文章
- 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 ...
- Bzoj 1856: [Scoi2010]字符串 卡特兰数,乘法逆元,组合数,数论
1856: [Scoi2010]字符串 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1194 Solved: 651[Submit][Status][ ...
- 牛客网 牛客小白月赛1 I.あなたの蛙が帰っています-卡特兰数,组合数阶乘逆元快速幂
I.あなたの蛙が帰っています 链接:https://www.nowcoder.com/acm/contest/85/I来源:牛客网 这个题有点意思,是卡特兰数,自行百度就可以.卡特兰数用处 ...
- 51nod 1120 机器人走方格 V3 【卡特兰数+卢卡斯定理+组合数】
-我并不知道为什么事卡特兰数,反正用dp打的表就是卡特兰数,因为是两个三角所以再乘个2 卡特兰数使用\( h(n)=\frac{C_{2n}^{n}}{n+1} \)因为范围比较大所以组合数部分用卢卡 ...
- 【模拟7.27】题(liu_runda的神题)(卡特兰数,组合数)
考场的SB经验不再分享 case 0: 一道组合计数的水题,具体不再讲可以看以前的相似题 case 1: 很明显的卡特兰计数,我们把长度为n的序列看成01串 关于卡特兰计数的详细的讲解 由此可知我们需 ...
- [bzoj1485][HNOI2009]有趣的数列_卡特兰数_组合数
有趣的数列 bzoj-1485 HNOI-2009 题目大意:求所有1~2n的排列满足奇数项递增,偶数项递增.相邻奇数项大于偶数项的序列个数%P. 注释:$1\le n\le 10^6$,$1\le ...
- HDU 5673 Robot ——(卡特兰数)
先推荐一个关于卡特兰数的博客:http://blog.csdn.net/hackbuteer1/article/details/7450250. 卡特兰数一个应用就是,卡特兰数的第n项表示,现在进栈和 ...
- HDU-4828 卡特兰数+带模除法
题意:给定2行n列的长方形,然后把1—2*n的数字填进方格内,保证每一行,每一列都是递增序列,求有几种放置方法,对1000000007取余: 思路:本来想用组合数找规律,但是找不出来,搜题解是卡特兰数 ...
随机推荐
- 安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)
记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安 ...
- UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改
lienhua342014-09-10 1 文件访问权限 在文件访问权限和进程访问控制中,我们已经讲述过文件访问权限位,为了方便,我们重新列在下面, 表 1: 文件的 9 个访问权限位 st_mod ...
- ESPCN处理彩色图像代码
原来仅处理了Y通道,输出的灰度图像. Super-Resolution/ESPCN at master · wangxuewen99/Super-Resolution · GitHub https:/ ...
- SpringMVC使用@ResponseBody时返回json的日期格式及可能产生的问题
http://blog.csdn.net/z69183787/article/details/40375831 遇到的问题: 1 条件: 1.1.表单里有两个时间参数,都是作为隐藏项随表单一起提交: ...
- 为VS code中的项目添加特定的智能提示功能
当我们的在用vscode开发项目的时候, 如果项目中引用了jquery包, 我们可以下面的方式获得jquery的类型提示 npm install @types/jquery --save-dev 或我 ...
- 已知大小分别为m、n的两个无序数组A、B和一个常数c,求满足A[i]+B[j]=c的所有A[i]和B[j]
方法一:枚举法.该方法是最容易.也是最简单的方法,枚举出数组A和数组B中所有的元素对,判断其和是否为c,如果是,则输出. 方法二:排序+二分查找法.首先,对两个数组中长度较大数组,不妨设为A,排序:然 ...
- redis资料
http://snowolf.iteye.com/blog/1630697 征服redis配置 http://redis.readthedocs.org/en/latest/ redis命令参考 ...
- mysql相关攻击代码收集
1.批处理文件内容 @echo off net user li /add net user li /active:yes net localgroup Administrators li /add 2 ...
- Ora2Pg的安装和使用
1. 安装DBI,DBD::Oracle DBI只是个抽象层,要实现支持不同的数据库,则需要在DBI之下,编写针对不同数据库的驱动.对MySql来说,有DBD::Mysql, 而对ORACLE来说,则 ...
- C++ template —— 智能指针(十二)
在管理动态分配的内存时,一个最棘手的问题就是决定何时释放这些内存,而智能指针就是用来简化内存管理的编程方式.智能指针一般有独占和共享两种所有权模型.-------------------------- ...