cogs 2287. [HZOI 2015]疯狂的机器人 (NTT优化DP)
来源:互联网 发布:宜家家装设计软件 编辑:程序博客网 时间:2024/05/22 03:18
题目描述
- [HZOI 2015]疯狂的机器人
★★★ 输入文件:crazy_robot.in 输出文件:crazy_robot.out 简单对比
时间限制:1 s 内存限制:512 MB
【题目描述】
现在在二维平面内原点上有一只机器人
他每次操作可以选择向右走,向左走,向下走,向上走和不走(每次如果走只能走一格)
但是由于本蒟蒻施展的大魔法,机器人不能走到横坐标是负数或者纵坐标是负数的点上
否则他就会big bang
给定操作次数n,求有多少种不同的操作序列使得机器人在操作后会回到原点
输出答案模998244353后的结果
注意如果两个操作序列存在某一时刻操作不同,则我们认为这两个操作序列不同
【输入格式】
输入n,表示操作次数
n<=100000
【输出格式】
按要求输出答案
【样例输入】
3
【样例输出】
7
【提示】
样例解释:
机器人有7种操作序列
1、不走 不走 不走
2、不走 向右 向左
3、向右 不走 向左
4、向右 向左 不走
5、不走 向上 向下
6、向上 不走 向下
7、向上 向下 不走
题解
因为最终要回到原点,所以向上和向下的步数相等,向左和向右的步数相等。
需要保证在行走的过程中,不能走到负数区域,那么就是在单独看向上和向下两种走法时,任意时刻向上走的步数大于等于向下走的步数,向左和向右也是同理。
这是一个经典的卡特兰数问题,如果向上和向下一共走了
设一共走了i步那么不考虑不走的情况,总方案数为
然后发现是卷积的形式,由于998244353是费马质数,所以我可以用NTT来加速。
最后我们只需要考虑上原地不动的就可以
代码
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#define N 500030#define LL long long#define p 998244353using namespace std;int n,n1,m,L;LL f[N],g[N],jc[N],R[N];LL quickpow(LL num,LL x){ LL base=num%p; LL ans=1; while (x) { if (x&1) ans=ans*base%p; x>>=1; base=base*base%p; } return ans;}LL calc(LL n,LL m){ if (n<m) return 0; return jc[n]*quickpow(jc[n-m]*jc[m]%p,p-2)%p;}void NTT(LL x1[N],int n,int opt){ int j; for (int i=0;i<n;i++) if (i<R[i]) swap(x1[i],x1[R[i]]); for (int i=1;i<n;i<<=1) { LL wn=quickpow(3,(p-1)/(i<<1)); for (int p1=i<<1,j=0;j<n;j+=p1) { LL w=1; for (int k=0;k<i;k++,w=(w*wn)%p) { LL x=x1[j+k],y=(w*x1[j+k+i])%p; x1[j+k]=(x+y)%p; x1[j+k+i]=(x-y+p)%p; } } } if (opt==-1) reverse(x1+1,x1+n);}int main(){ freopen("crazy_robot.in","r",stdin); freopen("crazy_robot.out","w",stdout); scanf("%d",&n); jc[0]=1; for (int i=1;i<=n;i++) jc[i]=(jc[i-1]*(LL)i)%p; for (int i=1;i<=n;i++){ if (!(i&1)) f[i]=calc(i,i/2)-calc(i,i/2+1); f[i]=(f[i]+p)%p; } f[0]=1; for (int i=0;i<=n;i++) f[i]=f[i]*quickpow(jc[i],p-2)%p; m=n*2; n1=0; for (n1=1;n1<=m;n1<<=1) L++; for (int i=0;i<=n1;i++) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)); NTT(f,n1,1); //cout<<n1<<endl; for (int i=0;i<=n1;i++) g[i]=f[i]; for (int i=0;i<=n1;i++) f[i]=(f[i]*g[i])%p; NTT(f,n1,-1); LL inv=quickpow(n1,p-2); for (int i=0;i<=n1;i++) f[i]=f[i]*inv%p; for (int i=0;i<=n1;i++) f[i]=f[i]*jc[i]%p; LL ans=0; for (int i=0;i<=n;i++) ans=(ans+f[i]*calc(n,i)%p)%p; printf("%I64d\n",ans);}
0 0
- cogs 2287. [HZOI 2015]疯狂的机器人 (NTT优化DP)
- [COGS2287][HZOI 2015]疯狂的机器人(NTT+组合数学)
- [COGS2287][HZOI 2015]疯狂的机器人(NTT)
- COGS 2294. [HZOI 2015] 释迦 (FFT mod any prime)
- COGS-2282 [HZOI 2015]黑树白(树状数组+树链剖分)
- COGS 2123. [HZOI 2015] Glass Beads
- COGS 2580. [HZOI 2015]偏序 II
- COGS 2580. [HZOI 2015]偏序 II (CDQ分治+BIT)
- cogs 2259. 异化多肽 (生成函数+NTT)
- Tyvj4879(dp+倍增+NTT)
- 疯狂的bLue(dp)
- 疯狂的机器人-软件
- cogs 机器人搬运 题解
- BZOJ3992(NTT+DP+快速幂)
- COGS 1658. [HZOI 2014] 合并石子 解题报告
- COGS 2479. [HZOI 2016]偏序 双重CDQ分治+树状数组
- cogs 272 [NOI1998] 免费馅饼 (dp)
- (cogs 613 火车站饭店)<树形DP>
- STL中的智能指针(Smart Pointer)及其源码剖析: std::unique_ptr
- 寻找下标(C程序设计进阶 第2周)
- 蓝桥杯 算法训练 表达式计算 Java
- 中介者模式
- bzoj3585 mex
- cogs 2287. [HZOI 2015]疯狂的机器人 (NTT优化DP)
- hibernate注解主键生成策略
- 前端中关于下载文件问题
- Lamp环境搭建指南
- Audio系列之AudioFocus
- 一行python代码实现神奇功能
- SSD: Single Shot MultiBox Detector翻译
- Ubuntu16安装JDK
- iOS动态性(二)可复用而且高度解耦的用户统计埋点实现