CF896D Nephren Runs a Cinema
CF896D Nephren Runs a Cinema
题意
售票员最开始没有纸币,每次来一个顾客可以给她一张、拿走她一张或不操作。求出不出现中途没钱给的情况 \(n\) 名顾客后剩余钱数在 \(l\sim r\) 的方案数。
思路
这是我们一道模拟赛题。
解法 1:套路组合计数。先不考虑不操作的顾客,那么就相当于是求二维平面不过一条直线到达一点的方案数。直接枚举操作顾客数,用组合数减去另外一个组合数然后乘上所有顾客中选这些顾客的方案数即可。
解法 2:暴力动态规划。每次从至多三个方向转移。
赛时我先想到第一个解法但是没想到枚举操作人数,以为不可做,于是想到了优化暴力的解法。
解法 3:解法 2 的优化。求出 \(F=(x^{-1}+1+x)^n\) ,然后 \(f(x)-f(x+2)\) 的第 \(l \sim r\) 项的和即为答案。
\((x^{-1}+1+x)\) 表示三种转移方式,但是求出来的 \(F\) 显然不是正确答案,因为会有从负数幂的贡献是应该减掉的。
那么我们就考虑减掉它,实际上和解法一相同,\(f(x)-f(x+2)\) 相当于减去了错解,那么减完之后就是答案了。
因为每次要倍长多项式,使用快速幂一样的方式卷就可以了。根据主定理,时间复杂度 \(O(n\log n)\)。
考场上有部分分,模数为 \(998244353\),那么正解只需要改成任意模数多项式乘法就行了。
代码
注意,此代码不可 AC 此题,仅在模数为 \(998244353\) 时正确。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdlib>
using namespace std;
inline int read(){
int x=0,w=0;char c=getchar();
while(!isdigit(c)) w|=c=='-',c=getchar();
while(isdigit(c)) x=x*10+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=2e6+10,mod=998244353,ge=3,gi=998244354/3;
inline int fpow(int a,int b){int ans=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;return ans;}
struct NTT{
int r[maxn],lim;
inline void getr(int li){lim=li;for(int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)*(lim>>1));}
inline void operator () (int *a,int type) const {
for(int i=0;i<lim;i++) if(i<r[i]) swap(a[i],a[r[i]]);
for(int mid=1;mid<lim;mid<<=1){
int rt=fpow(type==1?ge:gi,(mod-1)/(mid<<1));
for(int r=mid<<1,j=0;j<lim;j+=r){
int p=1;
for(int k=0;k<mid;k++,p=1ll*p*rt%mod){
int x=a[j+k],y=1ll*p*a[j+k+mid]%mod;
a[j+k]=(x+y)%mod,a[j+k+mid]=(x-y+mod)%mod;
}
}
}
if(type==-1) for(int p=fpow(lim,mod-2),i=0;i<lim;i++) a[i]=1ll*a[i]*p%mod;
}
}ntt;
int n;
int a[maxn],ans[maxn];
inline void work(){
n=read();read();
int Lim=4,lim=2;
a[0]=a[1]=a[2]=ans[0]=1;
int x=n,Len=3,len=1;
while(x){
static int res[maxn],tmp[maxn];
if(x&1){
for(int i=0;i<Lim;i++) res[i]=a[i];
for(int i=Lim;i<Lim+lim;i++) res[i]=0;
for(int i=0;i<lim;i++) tmp[i]=ans[i];
for(int i=lim;i<Lim+lim;i++) tmp[i]=0;
len+=Len;lim=Lim;
while(lim<len) lim<<=1;
ntt.getr(lim<<1);
ntt(res,1),ntt(tmp,1);
for(int i=0;i<lim<<1;i++) tmp[i]=1ll*res[i]*tmp[i]%mod;
ntt(tmp,-1);
for(int i=0;i<lim;i++) ans[i]=tmp[i];
}
for(int i=0;i<Lim;i++) res[i]=a[i];
for(int i=Lim;i<Lim<<1;i++) res[i]=0;
Lim<<=1;Len<<=1;
for(int i=Lim;i<Lim<<1;i++) res[i]=0;
ntt.getr(Lim<<1);
ntt(res,1);
for(int i=0;i<Lim<<1;i++) res[i]=1ll*res[i]*res[i]%mod;
ntt(res,-1);
for(int i=0;i<Lim;i++) a[i]=res[i];
x>>=1;
}
int l=read(),r=read();
for(int i=n;i<n<<1;i++) ans[i]=(ans[i]-ans[i+2]+mod)%mod;
int Ans=0;
for(int i=n+l;i<=n+r;i++) Ans=(Ans+ans[i])%mod;
printf("%d\n",Ans);
}
}
signed main(){
star::work();
return 0;
}
CF896D Nephren Runs a Cinema的更多相关文章
- 【CF896D】Nephren Runs a Cinema 卡特兰数+组合数+CRT
[CF896D]Nephren Runs a Cinema 题意:一个序列中有n格数,每个数可能是0,1,-1,如果一个序列的所有前缀和都>=0且总和$\in [L,R]$,那么我们称这个序列是 ...
- 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#896 D-Nephren Runs a Cinema
容易发现这些 vip 用户并没什么用,所以考虑枚举手持50元与100元的人共有多少个.设手持50元的人 \(a\) 个,手持100元的人 \(a - k\) 个,那么一共是 \(2*a - k\) 个 ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- Codeforces #380 div2 C(729C) Road to Cinema
C. Road to Cinema time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2)C. Road to Cinema 二分
C. Road to Cinema time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- cf380D Sereja and Cinema 组合数学
time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...
- Cinema 4D R16安装教程
CINEMA 4D_百度百科 http://baike.baidu.com/view/49453.htm?fr=aladdin 转自百度贴吧 [教程]Cinema 4D R16新功能介绍及安装教程_c ...
- ZOJ 3635 Cinema in Akiba(线段树)
Cinema in Akiba (CIA) is a small but very popular cinema in Akihabara. Every night the cinema is ful ...
随机推荐
- SpringAOP 原理解析
什么是AOP? 1: 传统的OOP编程他的代码逻辑是一种自上向下, 而在这些自上而下的过程中会产生一些横切性的问题,比如说:日志信息,权限校验认证,事务等, 2: 这些横切性问题,往往与我们的主业务逻 ...
- servlet、过滤器、监听器、拦截器之间的关系和区别
一.概念 1.什么是servlet servlet是一个接口.定义了一套处理网络请求的规范,所有实现servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法 init()和destr ...
- 「题解」USACO15FEB Fencing the Herd G
本文将同步发布于: 洛谷博客: csdn: 博客园: 简书: 题目 题目链接:洛谷 P3122.USACO 官网. 题意概述 给你平面上的一些点和直线,有两种操作: 新加入一个点 \((x,y)\): ...
- 【NX二次开发】Block UI 目录
Block UI 目录 基本 标签/位图 切换开关 枚举 字符串 多行字符串 操作按钮 列表框 分割线 对象颜色选择器 RGB颜色选择器 绘图区 图层 ...
- 【NX二次开发】Block UI 通过浏览选择文件夹
属性说明 属性 类型 描述 常规 BlockID String 控件ID Enable Logical 是否可操作 Group ...
- 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记番外(1) - JLinkScript妙用
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记番外篇之JLinkScript妙用. JLinkScript 文件是配套 J-Link 调试器使用的脚本,这个脚本适 ...
- 基于Colab Pro & Google Drive的Kaggle实战
原文:https://hippocampus-garden.com/kaggle_colab/ 原文标题:How to Kaggle with Colab Pro & Google Drive ...
- 屌炸天,像写代码一样写PPT,一个小工具解决
此文已经废,请移步升级版博文: markdown写ppt (史上最全)
- 基于websocket vue 聊天demo 解决方案
基于websocket vue 聊天demo 解决方案 demo 背景 电商后台管理的客服 相关技术 vuex axios vue websocket 聊天几种模型 一对一模型 一对一 消息只一个客户 ...
- CloudCanal
CloudCanal 是一款数据迁移同步工具,帮助企业快速构建高质量数据流通通道,产品包含 SaaS 模式和私有输出专享模式.开发团队核心成员来自大厂,具备数据库内核.大规模分布式系统.云产品构建背景 ...