zoukankan      html  css  js  c++  java
  • 【模拟7.27】题(liu_runda的神题)(卡特兰数,组合数)

    考场的SB经验不再分享

    case 0:

    一道组合计数的水题,具体不再讲可以看以前的相似题

    case 1:

    很明显的卡特兰计数,我们把长度为n的序列看成01串

    关于卡特兰计数的详细的讲解

    由此可知我们需要满足从1——n中前缀1的数量不少于前缀0的数量

    case 2:

    满足可以在坐标轴上移动

    设f[i]表示第i步回到原点,我们枚举第j步第一次回到起点

    那么f[i]数组里就不会出现重复,这样可以保证正确性

    同时要再次用到卡特兰数:

       我们发现定义的特殊j是第一次回到起点,但cal中可以多次回到起点

    但我们可以发现只要我们满足在1-j-1满足前缀和>=1即可,这样我们可以

    发现现在序列一部分确定设正方向为1

        1 1 .........0 0

    这样中间部分就又是一个cal,这样我们直接乘cal(j/2-1)即可

    (注意可能j是四个方向,于是乘4)

    case 3:

    同时在两轴及第一象限

    直接用组合数,乘两个方向的cal即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<stack>
     8 #include<map>
     9 #include<queue>
    10 #define ps push_back
    11 #define MAXN 1000001
    12 #define ll long long
    13 using namespace std;
    14 ll n;
    15 const ll mod=1000000007;
    16 ll jie[MAXN],ni[MAXN],ni_c[MAXN];
    17 ll C(ll x,ll y)
    18 {
    19     if(y>x)return 0;
    20     return jie[x]*ni_c[y]%mod*ni_c[x-y]%mod;
    21 }
    22 ll cal(ll x)
    23 {
    24      return C(x*2,x)*ni[x+1]%mod;
    25 }
    26 ll f[MAXN];
    27 int main()
    28 {
    29       ll orz;
    30       scanf("%lld%lld",&n,&orz);
    31       jie[0]=1;jie[1]=1;
    32       ni[0]=1;ni[1]=1;
    33       ni_c[0]=1;ni_c[1]=1;
    34       for(ll i=2;i<=2*n+10;++i)
    35       {
    36          jie[i]=(jie[i-1]*i)%mod;
    37          ni[i]=((mod-mod/i)*ni[mod%i])%mod;
    38          ni_c[i]=(ni_c[i-1]*ni[i])%mod;
    39       }
    40       ll ans=0;
    41       if(orz==0)
    42       {
    43           for(ll i=0;i<=n;i+=2)
    44           {
    45                ans=(ans+C(n,i)*C(i,i/2)%mod*C(n-i,(n-i)/2))%mod;
    46           }
    47           printf("%lld
    ",ans%mod);
    48       }
    49       else if(orz==1)
    50       {
    51           if(n%2==1)
    52                printf("0
    ");
    53           else
    54                printf("%lld
    ",(C(n,n/2)%mod*ni[n/2+1]%mod+mod)%mod);
    55       }
    56       else if(orz==3)
    57       {
    58           for(ll i=0;i<=n;i+=2)
    59           {
    60                ll th=C(n,i);
    61                if((n-i)%2==1)continue;
    62                ans=(ans+th*cal(i/2)%mod*cal((n-i)/2))%mod;
    63           }     
    64           printf("%lld
    ",ans);
    65       }
    66       else if(orz==2)
    67       {
    68            f[0]=1;
    69            for(ll i=2;i<=n;i+=2)
    70            {
    71                for(ll j=0;j<=i;j+=2)
    72                {
    73                     f[i]=(f[i]+4*f[i-j]*cal(j/2-1))%mod;
    74                }
    75            }
    76            printf("%lld
    ",f[n]);
    77       }
    78 }
    View Code
  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11255270.html
Copyright © 2011-2022 走看看