• Luogu P3266 [JLOI2015]骗我呢


    Link
    观察到每行只能是在([0,m])中选择一个不出现的数,然后剩下的升序排列。
    假如第(i)行不出现的数是(j),那么(i-1)行不出现的数必须是([0,j-1])
    因此我们可以设计一个dp,设(f_{i,j})表示只考虑前(i)行,第(i)行不出现的数是(j)的方案数,那么显然有:
    (f_{i,j}=sumlimits_{k=0}^{j+1}f_{i-1,k}=f_{i,j-1}+f_{i-1,j+1})(为了方便转移(j)的上界是(m+1))。
    这样初始状态就是(f_{0,0}=1),答案就是(f_{n,m+1})
    考虑转化为格路问题,(f_{n,m+1})就是从((0,0))走到((n,n+m+1)),每次只能向上或向右走,不能碰到(l_1:x-y=0,l_2:x-y+m+1=0)两条直线的方案数。
    再设(f(x,y),g(x,y))表示先碰到(l_1,l_2)到达((x,y))的方案数。
    利用补集容斥得到(f_{n,m+1}={2n+m+1choose n}-(f(n,n+m+1)+g(n,n+m+1)))
    考虑经典做法对称,(f(n,n+m+1)=f(n+m+2,n-1),g(n,n+m+1)=g(n-1,n+m+2))
    此时(f(x,y),g(x,y))一定满足(y-x<0vee y-x>m+1),因此((0,0))((x,y))一定会越过边界,即(f(x,y)+g(x,y)={x+ychoose x})
    再次对称可以得到(f(x,y)={x+ychoose x}-g(y-m-2,x+m+2),g(x,y)={x+ychoose x}-f(y+1,x-1))
    这样就能保证递归求解时(f(x,y),g(x,y))都满足(y-x<0vee y-x>m+1)了。
    边界条件为(f(x,y)=g(x,y)=0qquad ext{where}quad x<0vee y<0)

    #include<cstdio>
    const int P=1000000007;
    int n,m,fac[3000007],ifac[3000007];
    int dec(int a,int b){return a-=b,a+=a>>31&P;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    int C(int n,int m){return mul(mul(fac[n],ifac[m]),ifac[n-m]);}
    int f(int,int);int g(int,int);
    int f(int x,int y){return x<0||y<0? 0:dec(C(x+y,x),g(y-m-2,x+m+2));}
    int g(int x,int y){return x<0||y<0? 0:dec(C(x+y,x),f(y+1,x-1));}
    int main()
    {
        scanf("%d%d",&n,&m),fac[0]=1;
        for(int i=1;i<=2*n+m+1;++i) fac[i]=mul(fac[i-1],i);
        ifac[2*n+m+1]=pow(fac[2*n+m+1],P-2);
        for(int i=2*n+m+1;i;--i) ifac[i-1]=mul(ifac[i],i);
        printf("%d",dec(dec(C(2*n+m+1,n),f(n+m+2,n-1)),g(n-1,n+m+2)));
    }
    
  • 相关阅读:
    简洁又漂亮的单网页404页源码(html格式404源码)
    运行bee run之后出现的错误以及解决方法
    window beego 安装出现的错误
    golang gin框架 使用swagger生成api文档
    go语言切片作为函数参数
    Go中函数接收器不能改变接收者的地址
    docker 删除none镜像
    redis下载安装
    git切换分支
    angular自定义验证器添加入模板驱动表单
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12252887.html
Copyright © 2020-2023  润新知