zoukankan      html  css  js  c++  java
  • [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]*inom{n}{i}$$
    $a[i]$表示向上向下(或向左向右)走i步回到原点的方案数
    显然i为偶数时才有方案否则$a[i]$为0
    然后不动就直接枚举f
    $$ans=sum_{i=0}^{n}f[i]*inom{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
    ",ans);
    82   return 0;
    83 }
  • 相关阅读:
    CF896C Willem, Chtholly and Seniorious 珂朵莉树
    LG2495 「SDOI2011」消耗战 虚树
    20191102 「HZOJ NOIP2019 Round #12」20191102模拟
    LG1345 「USACO5.4」Telecowmunication 最小割
    LG1344 「USACO4.4」Pollutant Control 最小割
    POJ1741 Tree 点分治
    [BZOJ2143]飞飞侠 并查集优化最短路
    [NOI.AC#41]最短路 线性基
    [NOI.AC#40]Erlang
    [BZOJ2238]Mst 最小生成树+树链剖分/并查集
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8377706.html
Copyright © 2011-2022 走看看