zoukankan      html  css  js  c++  java
  • [JLOI2015] 骗我呢

    Description

    求从 \((0,0)\) 走到 \((n,m)\) 而不经过某两条形如 \(y=x+b\) 的直线的方案数。

    Solution

    \(A\) 表示经过 \(l_1\) 的事件,\(B\) 表示经过 \(l_2\) 的事件。首先,连续两次 \(A\)\(B\),可以只看第一次。所以一条不合法路径对应 \(ABAB\dots\)\(BABA\dots\) 的一个前缀。

    所以方案是 \(\binom{n+m}{n}-以 A 开头的路径-以 B 开头的路径\)。以 \(A\)\(B\) 开头是类似的,我们只考虑 \(A\) 开头。类似卡特兰数求法,把 \((n,m)\) 沿着 \(l_1\) 对称,得到 \((n',m')\)\(\binom{n'+m'}{n'}\) 就是至少包含一次 \(A\) 的方案数。这个方案包含了以 \(A\)\(BA\) 为前缀的所有路径,所以需要减去 以 \(BA\) 为前缀的路径。再把 \((n',m')\) 沿着 \(l_2\) 对称,这次求出的方案就包含了以 \(BA\)\(ABA\) 为前缀的路径,所以再加上 \(ABA\)……。一直递归下去,每翻折两次,就会使得 \((n,m)\) 变为 \((n+k,m-k)\),当其中一维小于 \(0\) 的时候,就不存在一种映射使得它对应于原路径,求出来的就是无效值。所以递归是有界的,且至多递归 \(O(\frac{n}{k})\) 次。\(B\) 的情况同理,只是先沿着 \(l_2\) 翻。

    #include<stdio.h>
    
    typedef long long ll;
    
    const int N=3e6+7;
    const int Mod=1e9+7;
    
    int n,m;
    ll fac[N],ifac[N],inv[N],ans=0;
    
    inline ll C(int x,int y){return x<y? 0:fac[x]*ifac[y]%Mod*ifac[x-y]%Mod;}
    
    inline void swap(int &x,int &y){x^=y^=x^=y;}
    inline void fold(int &x,int &y,bool typ,int op){
        swap(x,y); int dt=typ? (m+2):-1;
        x+=dt,y-=dt; ans=(ans+Mod+op*(x>=0&&y>=0? C(x+y,x):0))%Mod;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        fac[0]=inv[1]=ifac[0]=1; for(int i=1;i<N;i++) fac[i]=fac[i-1]*i%Mod;
        for(int i=2;i<N;i++) inv[i]=(Mod-Mod/i)*inv[Mod%i]%Mod;
        for(int i=1;i<N;i++) ifac[i]=ifac[i-1]*inv[i]%Mod; ans=C(n*2+m+1,n);
        int x=n+m+1,y=n; while(x>=0&&y>=0) fold(x,y,0,-1),fold(x,y,1,1);
        x=n+m+1,y=n; while(x>=0&&y>=0) fold(x,y,1,-1),fold(x,y,0,1);
        printf("%lld",ans);
    }
    
  • 相关阅读:
    利用Python 统计txt 文档词频 次数
    Markdown工具Typora结合gitee码云图床自动上传云端图片
    主数据MDM下发eHR系统操作整理v1.0
    Python读取Excel数据生成图表 v2.0
    HTML基础(20200610)
    Python网络编程socket 简易聊天窗
    selenium-python-验证码-动态验证码
    selenium-python-验证码-滑动验证码
    Linux系统学习 20200506
    @Mapper @Insert 注解式方法批量入库(ORACLE数据库)
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15543277.html
Copyright © 2011-2022 走看看