【题目描述】

现在在二维平面内原点上有一只机器人

他每次操作可以选择向右走,向左走,向下走,向上走和不走(每次如果走只能走一格)

但是由于本蒟蒻施展的大魔法,机器人不能走到横坐标是负数或者纵坐标是负数的点上

否则他就会big bang

给定操作次数n,求有多少种不同的操作序列使得机器人在操作后会回到原点

输出答案模998244353后的结果

注意如果两个操作序列存在某一时刻操作不同,则我们认为这两个操作序列不同

【输入格式】

输入n,表示操作次数

n<=100000

【输出格式】

按要求输出答案

【样例输入】

3

【样例输出】

7

【提示】

样例解释:

机器人有7种操作序列

1、不走 不走 不走

2、不走 向右 向左

3、向右 不走 向左

4、向右 向左 不走

5、不走 向上 向下

6、向上 不走 向下

7、向上 向下 不走

正解:组合数学+$NTT$。

学习卡特兰数以后做这题好像不难?

我们把操作分为$3$类,向右和向左为一类,向上和向下为一类,不动为一类。

那么如果只考虑前两类中的任何一类,那就是卡特兰数,因为这就是要求有$n/2$个$+1$,$-1$,且所有前缀和都$>=0$的序列方案数。很显然,只有偶数能取前两种情况。

那么我们扩展一下,如果有前两种操作,该怎么做?

$f[n]$表示$n$步路回到原点的方案数,那么$f[n]=\sum_{i=0}^{n}a[i]*a[n-i]*\binom{n}{i}$。

$a[i]$表示前两类操作走$i$步的方案数,$a[i]=c[i/2]$,当且仅当$i$为偶数,$c$为卡特兰数。

也就是说,从第一类操作中选$i$步,第二类操作中选$n-i$步,最后再组合起来,就是这个方案。

上式我们已经可以用$NTT$优化,做到$O(nlogn)$的复杂度。

考虑第$3$中操作,其实很简单了。我们只要枚举前两个操作总共有多少步,再和第$3$个操作组合一下就行。

也就是$Ans=\sum_{i=0}^{n}f[i]*\binom{n}{i}$。

 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define rhl (998244353)
#define N (500010) using namespace std; int inv[N],fac[N],ifac[N],a[N],c[N],rev[N],n,m,lg,ans; il int qpow(RG int a,RG int b){
RG int ans=;
while (b){
if (b&) ans=1LL*ans*a%rhl;
a=1LL*a*a%rhl,b>>=;
}
return ans;
} il void pre(){
fac[]=ifac[]=fac[]=ifac[]=inv[]=;
for (RG int i=;i<=(n<<);++i){
inv[i]=1LL*(rhl-rhl/i)*inv[rhl%i]%rhl;
fac[i]=1LL*fac[i-]*i%rhl;
ifac[i]=1LL*ifac[i-]*inv[i]%rhl;
}
return;
} il void NTT(int *a,RG int n,RG int f){
for (RG int i=;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (RG int i=;i<n;i<<=){
RG int gn=qpow(,(rhl-)/(i<<)),x,y;
for (RG int j=,g=;j<n;j+=i<<,g=)
for (RG int k=;k<i;++k,g=1LL*g*gn%rhl){
x=a[j+k],y=1LL*g*a[j+k+i]%rhl;
a[j+k]=x+y; if (a[j+k]>=rhl) a[j+k]-=rhl;
a[j+k+i]=x-y; if (a[j+k+i]<) a[j+k+i]+=rhl;
}
}
if (f==) return; reverse(a+,a+n); RG int inv=qpow(n,rhl-);
for (RG int i=;i<n;++i) a[i]=1LL*a[i]*inv%rhl;
return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("robot.in","r",stdin);
freopen("robot.out","w",stdout);
#endif
cin>>n; pre();
for (RG int i=;i<=n;++i)
c[i]=1LL*fac[i<<]*ifac[i]%rhl*ifac[i]%rhl*inv[i+]%rhl;
for (m=;m<=(n<<);m<<=) ++lg; a[]=;
for (RG int i=;i<=n;++i) if (!(i&)) a[i]=1LL*c[i>>]*ifac[i]%rhl;
for (RG int i=;i<m;++i) rev[i]=rev[i>>]>>|((i&)<<(lg-));
NTT(a,m,); for (RG int i=;i<m;++i) a[i]=1LL*a[i]*a[i]%rhl;
NTT(a,m,-); for (RG int i=;i<=n;++i) a[i]=1LL*a[i]*fac[i]%rhl;
for (RG int i=;i<=n;++i)
ans=(ans+1LL*a[i]*fac[n]%rhl*ifac[i]%rhl*ifac[n-i])%rhl;
printf("%d\n",ans); return ;
}

COGS2287 [HZOI 2015]疯狂的机器人的更多相关文章

  1. BZOJ 2287. [HZOI 2015]疯狂的机器人 [FFT 组合计数]

    2287. [HZOI 2015]疯狂的机器人 题意:从原点出发,走n次,每次上下左右不动,只能在第一象限,最后回到原点方案数 这不煞笔提,组合数写出来发现卷积NTT,然后没考虑第一象限gg 其实就是 ...

  2. 【COGS】2287:[HZOI 2015]疯狂的机器人 FFT+卡特兰数+排列组合

    [题意][COGS 2287][HZOI 2015]疯狂的机器人 [算法]FFT+卡特兰数+排列组合 [题解]先考虑一维的情况,支持+1和-1,前缀和不能为负数,就是卡特兰数的形式. 设C(n)表示第 ...

  3. [COGS 2287][HZOI 2015]疯狂的机器人

    Description 题库链接 现在在二维平面内原点上有一只机器人,他每次可以选择向右走,向左走,向下走,向上走和不走(每次如果走只能走一格).机器人不能走到横坐标是负数或者纵坐标是负数的点上. 给 ...

  4. [HZOI 2015]疯狂的机器人

    [题目描述] 现在在二维平面内原点上有一只机器人 他每次操作可以选择向右走,向左走,向下走,向上走和不走(每次如果走只能走一格) 但是由于本蒟蒻施展的大魔法,机器人不能走到横坐标是负数或者纵坐标是负数 ...

  5. cojs 疯狂的重心 疯狂的机器人 题解报告

    疯狂的重心 话说做过幻想乡战略游戏的人应该很容易切掉这道题目吧 我们考虑一棵树如果添加了一个叶子,那么其重心最多向叶子方向移动1的距离 而是否移动我们只需要记录子树中有多少个点就可以判断啦 也就是说这 ...

  6. Bitset([HZOI 2015]偏序++)

    Bitset简介 下面介绍C++ STL 中一个非常有用的东西: Bitset 类似于二进制状压,它可以把信息转化成一个01串存储起来 定义方法: 首先要#include<bitset>或 ...

  7. [cogs2314][HZOI 2015] Persistable Editor - 可持久化平衡树

    [cogs2314][HZOI 2015]Persistable Editor - 可持久化平衡树 题目链接 首先吐槽扯淡几句 [题目描述] 维护一种可持久化的文本编辑器,支持下列操作: 1 p st ...

  8. cogs 2123. [HZOI 2015] Glass Beads

    2123. [HZOI 2015] Glass Beads ★★★   输入文件:MinRepresentations.in   输出文件:MinRepresentations.out   简单对比时 ...

  9. COGS 2580. [HZOI 2015]偏序 II

    COGS 2580. [HZOI 2015]偏序 II 题目传送门 题目大意:给n个元素,每个元素有具有4个属性a,b,c,d,求i<j并且ai<aj,bi<bj,ci<cj, ...

随机推荐

  1. Jenkins自动化CI CD流水线之4--Master-Slave架构

    一.介绍 jenkins的Master-slave分布式架构主要是为了解决jenkins单点构建任务多.负载较高.性能不足的场景. Master/Slave相当于Server和agent的概念.Mas ...

  2. mysqldump的用法

    1.mysqldump 是文本备份还是二进制备份 它是文本备份,如果你打开备份文件你将看到所有的语句,可以用于重新创建表和对象.它也有 insert 语句来使用数据构成表. mysqldump可产生两 ...

  3. Java字符串拆分和字符串连接

    Java字符串拆分/连接 public class LierString{ //------------------------------------------------------------ ...

  4. python升级到3.*版本

    转载https://blog.csdn.net/liang19890820/article/details/51079633 简述 CentOS 7 中默认安装了 Python,版本比较低(2.7.5 ...

  5. thinkphp引入模板view

    3.1 模板放在哪儿? 放在模块的view目录下并且每个控制器的模板,要在与控制器同名的目录下. 以 index.php/Home/User/add则对应的模板在 /Home/view/User/ad ...

  6. js 获取非行间样式

    1.getComputedStyle(nodeObj,false):该方法是BOM对象,第一个是要获取样式的节点对象:第二个可以写成任何的字符一般写成false或者null,这里最好是用false因为 ...

  7. Java日志组件1---Jdk自带Logger(java.util.logging.Logger)

    最近在看日志的一些东西,发现利用JDK自带的log也可以简单的实现日志的输出,将日志写入文件的过程记录如下: 1.新建LogUtil.Java( 里面写了几个静态方法,为log设置等级.添加log控制 ...

  8. Linux添加、创建新用户

    给Linux添加新用户,新建用户,新建帐号 添加用户组 sudo groupadd groupname 添加用户 sudo useradd username -m -s /bin/bash -d /h ...

  9. python单元测试框架-unittest(四)之用例综合框架管理

    简述为何如要框架? 前面测试用例与执行都是写在一个文件,当用例数量不断增加的时候,用例的执行与管理变得非常麻烦,因此需要对用例根据具体的功能模块来使用单独的模块来管理.就像一所学校要根据不同年级进行分 ...

  10. jQuery源代码学习笔记_工具函数_noop/error/now/trim

    jQuery源代码学习笔记_工具函数_noop/error/now/trim jquery提供了一系列的工具函数,用于支持其运行,今天主要分析noop/error/now/trim这4个函数: 1.n ...