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的更多相关文章

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

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

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

  3. 【题解】CF#896 D-Nephren Runs a Cinema

    容易发现这些 vip 用户并没什么用,所以考虑枚举手持50元与100元的人共有多少个.设手持50元的人 \(a\) 个,手持100元的人 \(a - k\) 个,那么一共是 \(2*a - k\) 个 ...

  4. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

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

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

  7. cf380D Sereja and Cinema 组合数学

              time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  8. Cinema 4D R16安装教程

    CINEMA 4D_百度百科 http://baike.baidu.com/view/49453.htm?fr=aladdin 转自百度贴吧 [教程]Cinema 4D R16新功能介绍及安装教程_c ...

  9. ZOJ 3635 Cinema in Akiba(线段树)

    Cinema in Akiba (CIA) is a small but very popular cinema in Akihabara. Every night the cinema is ful ...

随机推荐

  1. 编译原理-非确定有穷自动机(nondeterministic finite automata,NFA)

    是一个五元组,M=(S,∑,f,S0,F) S:有穷状态集 ∑:输入字母表(有穷) f:f(S,α)=S' 表示从一个状态S出发,识别了一个字α后,可以到达S'这个状态集合之间的某一个状态(可能的后继 ...

  2. C#开发之基于NPOI的操作Excel开发体验

    最近遇到一个数据导入的需求,语言是.net framework 4.7的C#.但是,这次主要探讨NPOI的体验,原则就是向前兼容.所以采用.xls的支持.网上的资料,我稍微整合了一些. #1 单元格下 ...

  3. 【NX二次开发】隐藏、显示对象UF_OBJ_set_blank_status

    隐藏.显示对象用UF_OBJ_set_blank_status() 查看对象显示情况用UF_OBJ_ask_display_properties() 效果: 源码: #include "Te ...

  4. WPF中ListView控件怎么添加新的tiem时滚动条一直在最下面

    listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1])

  5. StringUtils中的常量

    //空格字符串 public static final String SPACE = " "; //空字符串 public static final String EMPTY = ...

  6. WEB 三维引擎在高精地图数据生产的探索和实践

    1. 前言 高精地图(High Definition Map)作为自动驾驶安全性不可或缺的一部分,能有效强化自动驾驶的感知能力和决策能力,提升自动驾驶的等级.对于自动驾驶来说,高精地图主要是给机器用的 ...

  7. 复习Spring第四课---Spring对国际化的支持

    其实国际化这东西很少使用,之前也就是粗略的学了下,趁今天有空,拿出来稍微写写.以前学android开发的时候,类似于多语言的版本.差别就是一个是手机打开,一个是浏览器打开,本质是一样的. 在Sprin ...

  8. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  9. 重新整理 .net core 实践篇————网关中的身份签名认证[三十七]

    前言 简单整理一下网关中的jwt,jwt用于授权认证的,其实关于认证授权这块https://www.cnblogs.com/aoximin/p/12268520.html 这个链接的时候就已经写了,当 ...

  10. centos 关闭SELINUX并重启系统

    关闭SELINUX [root@bogon ~]# vim /etc/sysconfig/selinux  ... SELINUX=disabled ... 执行过程: 重启系统 [root@bogo ...