[HZOI 2015]疯狂的机器人

【题目描述】

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

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

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

否则他就会big bang

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

输出答案模998244353后的结果

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

【输入格式】

输入n,表示操作次数

n<=100000

【输出格式】

按要求输出答案

【样例输入】

3

【样例输出】

7

【提示】

样例解释:

机器人有7种操作序列

1、不走 不走 不走

2、不走 向右 向左

3、向右 不走 向左

4、向右 向左 不走

5、不走 向上 向下

6、向上 不走 向下

7、向上 向下 不走

将操作分3类:向上下,向左右,不动
$f[i]$表示只考虑前两类走i步到原点的方案数
$$f[n]=\sum_{i=0}^{n}a[i]*a[n-i]*\binom{n}{i}$$
$a[i]$表示向上向下(或向左向右)走i步回到原点的方案数
显然i为偶数时才有方案否则$a[i]$为0
然后不动就直接枚举f
$$ans=\sum_{i=0}^{n}f[i]*\binom{n}{i}$$
$a[i]$显然就是卡特兰数第$i/2$项
因为任意时刻向上的前缀和总是大于向下的
至于卷积就直接把组合数拆开,把分母分到a上,即:
$$a[i]=C[i/2]*i!^{-1}$$
NTT求出f后再乘上$n!$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef int lol;
 8 const int N=100000;
 9 int Mod=998244353;
10 int G=3;
11 int a[8*N],fac[5*N],R[8*N],ifac[5*N],inv[5*N],c[5*N],f[8*N],ans;
12 int qpow(int x,int y)
13 {
14   int res=1;
15   while (y)
16     {
17       if (y&1) res=1ll*res*x%Mod;
18       x=1ll*x*x%Mod;
19       y>>=1;
20     }
21   return res;
22 }
23 void NTT(int *A,int len,int o)
24 {int wn,w,i,j,k,x,y;
25   for (i=0;i<len;i++)
26     if (i<R[i]) swap(A[i],A[R[i]]);
27   for (i=1;i<len;i<<=1)
28     {
29       wn=qpow(G,(Mod-1)/(i<<1));
30       if (o==-1) wn=qpow(wn,Mod-2);
31       for (j=0;j<len;j+=(i<<1))
32     {
33       w=1;
34       for (k=0;k<i;k++,w=1ll*w*wn%Mod)
35         {
36           x=A[j+k];y=1ll*w*A[j+k+i]%Mod;
37           A[j+k]=x+y;
38           if (A[j+k]>=Mod) A[j+k]-=Mod;
39           A[j+k+i]=x-y;
40           if (A[j+k+i]<0) A[j+k+i]+=Mod;
41         }
42     }
43     }
44   if (o==-1)
45     {
46       int tmp=qpow(len,Mod-2);
47       for (i=0;i<len;i++)
48     A[i]=1ll*A[i]*tmp%Mod;
49     }
50 }
51 int main()
52 {
53   int i,len,lg,n;
54   scanf("%d",&n);
55   memset(a,0,sizeof(a));
56   fac[0]=fac[1]=ifac[0]=ifac[1]=inv[1]=1;
57   for (i=2;i<=n*2;i++)
58     {
59       inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod;
60       fac[i]=1ll*fac[i-1]*i%Mod;
61       ifac[i]=1ll*ifac[i-1]*inv[i]%Mod;
62     }
63   for (i=1;i<=n;i++)
64     c[i]=1ll*fac[i<<1]*ifac[i]%Mod*ifac[i]%Mod*inv[i+1]%Mod;
65   a[0]=1;
66   for (i=2;i<=n;i++)
67     if ((i&1)==0)
68       a[i]=1ll*c[i>>1]*ifac[i]%Mod;
69   len=1;
70   while (len<=2*n) len*=2,lg++;
71   for (i=0;i<len;i++)
72     R[i]=(R[i>>1]>>1)|((i&1)<<(lg-1));
73   NTT(a,len,1);
74   for (i=0;i<len;i++)
75     a[i]=1ll*a[i]*a[i]%Mod;
76   NTT(a,len,-1);
77   for (i=0;i<=n;i++)
78     f[i]=1ll*a[i]*fac[i]%Mod;
79   for (i=0;i<=n;i++)
80     ans=1ll*(ans+1ll*f[i]*fac[n]%Mod*ifac[i]%Mod*ifac[n-i]%Mod)%Mod;
81   printf("%d\n",ans);
82   return 0;
83 }

 

posted @ 2018-01-29 15:48  Z-Y-Y-S  阅读(274)  评论(0编辑  收藏  举报