大家说他是卡特兰数,其实也不为过,一开始只是用卡特兰数来推这道题,一直没有怼出来,后来发现其实卡特兰数只不过是一种组合数学,我们可以退一步直接用组合数学来解决,这道题运用组合数的思想主要用到补集与几何法。

假设以矩形左下角为坐标原点,(以下所说路径均满足只能向右或向上走),我们假设原矩阵为a,那么他关于l(y=x+1),对称矩形就是b(黑色),那么出现了c矩阵,他的长为n+1,宽为m-1,易知从(0,0)到(n,m)(a右上角)的路径(在矩形a内)的种数就是C(n+m,m),然后我告诉你从(0,0)到(m-1,n+1)(c右上角)的路径(在矩形c内)种数C(n+m,m-1),就是原矩阵中不合法路径个数,你不信很正常.....

那么让我们想一下。从(0,0)到(n,m)的不合法路径(在矩形a内)一定满足若干次碰到了l与a围成的三角型的边界之一——l在a内部分,然后在最后一次碰到后离开并驶向(n,m),从(0,0)到(m-1,n+1)的路径(在矩形c内)均满足若干次碰到了l与a围成的三角型,然后在最后一次碰到后离开并驶向(m-1,n+1),再然后我们发现在“离开”之前的走法满足以上两种路径可以吻合,那么“离开“之后呢——他离开时一定最后与l交于一点,那么我们发现在l上的任意整点(在a内部分)与(n,m)和(m-1,n+1)分别作为两个对角点形成的矩形全等,于是从一角到另一角的方案一一对应,于是证毕。

#include <cstdio>
#include <cstring>
const int P=;
struct Bigint{
int a[];
Bigint(){a[]=a[]=;}
inline friend Bigint operator - (Bigint a,Bigint b);
inline friend Bigint operator * (Bigint a,int b);
inline void operator -= (Bigint b){(*this)=(*this)-b;}
inline void operator *= (int b){(*this)=(*this)*b;}
inline void print();
}ans1,ans2;
inline void Bigint:: print(){
printf("%d",a[a[]]);
for(int i=a[]-;i>;--i)
printf("%04d",a[i]);
}
inline Bigint operator - (Bigint a,Bigint b){
for(int i=;i<=a.a[];++i){
a.a[i]-=b.a[i];
if(a.a[i]<)
a.a[i]+=P,a.a[i+]--;
}
while(a.a[a.a[]]==)a.a[]--;
return a;
}
inline Bigint operator * (Bigint a,int b){
int last=;
for(int i=;i<=a.a[];++i)
a.a[i]=a.a[i]*b+last,last=a.a[i]/P,a.a[i]%=P;
if(last)a.a[++a.a[]]=last;
return a;
}
int n,m;
int prime[P+],len,mini[P+];
bool isnot[P+];
inline void get_prime(){
for(int i=;i<=P;++i){
if(isnot[i]==false)prime[++len]=i,mini[i]=len;
for(int j=;prime[j]*i<=P;++j){
isnot[prime[j]*i]=true,mini[prime[j]*i]=j;
if(i%prime[j]==)break;
}
}
}
int size[P];
int main(){
scanf("%d%d",&n,&m),get_prime();
for(int i=n+m,x;i>n;--i){
x=i;
while(mini[x])
++size[mini[x]],x/=prime[mini[x]];
}
for(int i=,x;i<=m;++i){
x=i;
while(mini[x])
--size[mini[x]],x/=prime[mini[x]];
}
for(int i=;i<=len;++i)
while(size[i])
ans1*=prime[i],--size[i];
for(int i=n+m,x;i>n+;--i){
x=i;
while(mini[x])
++size[mini[x]],x/=prime[mini[x]];
}
for(int i=,x;i<m;++i){
x=i;
while(mini[x])
--size[mini[x]],x/=prime[mini[x]];
}
for(int i=;i<=len;++i)
while(size[i])
ans2*=prime[i],--size[i];
ans1-=ans2;
ans1.print();
return ;
}

【BZOJ 3907】网格 组合数学的更多相关文章

  1. bzoj 3907: 网格 组合数学

    3907: 网格 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 13  Solved: 7[Submit][Status][Discuss] Descr ...

  2. BZOJ 3907: 网格( 组合数 + 高精度 )

    (0,0)->(n,m)方案数为C(n,n+m), 然后减去不合法的方案. 作(n,m)关于y=x+1的对称点(m-1,n+1), 则(0,0)->(m-1,n+1)的任意一条路径都对应( ...

  3. BZOJ 3907: 网格 [Catalan数 高精度]

    3907: 网格 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 402  Solved: 180[Submit][Status][Discuss] De ...

  4. BZOJ 3907: 网格【组合数学】

    Description 某城市的街道呈网格状,左下角坐标为A(0, 0),右上角坐标为B(n, m),其中n >= m.现在从A(0, 0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过 ...

  5. BZOJ 3907: 网格

    Description 求不跨过直线 \(y=x\) ,到达 \((n,m)\) 的方案数. Sol 组合数学+高精度. 这个推导过程跟 \(Catalan\) 数是一样的. 答案就是 \(C^{n+ ...

  6. bzoj 3907 网格 bzoj2822 [AHOI2012]树屋阶梯——卡特兰数(阶乘高精度模板)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3907 https://www.lydsy.com/JudgeOnline/problem.p ...

  7. 【BZOJ 3907】网格(Catalan数)

    题目链接 这个题推导公式跟\(Catalan\)数是一样的,可得解为\(C_{n+m}^n-C_{n+m}^{n+1}\) 然后套组合数公式\(C_n^m=\frac{n!}{m!(n-m)!}\) ...

  8. BZOJ 3997: [TJOI2015]组合数学 [偏序关系 DP]

    3997: [TJOI2015]组合数学 题意:\(n*m:\ n \le 1000\)网格图,每个格子有权值.每次从左上角出发,只能向下或右走.经过一个格子权值-1.至少从左上角出发几次所有权值为0 ...

  9. BZOJ 3997 [TJOI2015]组合数学(单调DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3997 [题目大意] 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右 ...

随机推荐

  1. php-5.6.26源代码 - include_once、require_once、include、require、eval 的opcode处理器

    # ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER 实现在文件 php-\Zend\zend_vm_execute.h static int ZEND_FASTCALL ...

  2. JZOJ 5934. 列队

    Description         Sylvia是一个热爱学习的女孩子.        在平时的练习中,他总是能考到std以上的成绩,前段时间,他参加了一场练习赛,众所周知,机房是一个 的方阵.这 ...

  3. PHP入门笔记--基础语法一

    一.基本语法 php标记 <?php ?> php代码结束标记 三种注释 // /**/ # 二.类型 四种标量类型:boolean, integer, float, string 三种复 ...

  4. while else

    count = 0 while count <= 5 : count += 1 if count == 3:pass print("Loop",count) else: pr ...

  5. 2018年第九届蓝桥杯【C++省赛B组】【第二题:明码】

    参考:https://blog.csdn.net/qq_34202873/article/details/79784242 #include <bits/stdc++.h> using n ...

  6. 贪心算法之Huffman

    Huffman编码,权重越大,离根节点越大.所以就是不断的选取两个最小的树,然后组成一颗新树,加入集合,然后去除已选的两棵树.不断的循环,直到最后的树的集合只剩下一棵,则构建完成,最后输出Huffma ...

  7. 【Leetcode】605. Can Place Flowers

    Description Suppose you have a long flowerbed in which some of the plots are planted and some are no ...

  8. css在线sprite

    大家知道网站图片多,浏览器下载多个图片要有多个请求.可是请求比较耗时,那怎么办呢? 对,方法就是css sprite. 今天我们来看看css在线sprite 百度搜索css-sprite 打开www. ...

  9. 如何打war包

    1. 利用jdk里的工具 例如我们要打包的文件在D:\myHome\dist: 运行 cmd: cd D:\myHome\dist 进入D:\myHome\dist 然后输入 D:\myHome\di ...

  10. CentOS7 添加自定义系统服务案例

    示例一: 执行脚本/root/project/systemctl/test.sh() ######################################################### ...