Iroha and a Grid AtCoder - 1974【组合数学-乘法逆元-快速幂】【数学好题】

题意简述:

有一个 H 行 W 列的网格。

Iroha 现在站在左上角 (1, 1)。 她每次会向右或向下走,直到走到右下角 (H, W)。

唯一的限制是,她不能走到左下方的 A 行 B 列。

求行走的方案数对 10 9 + 7 取模

数据范围:

  • 1 ≦ H, W ≦ 100,000
  • 1 ≦ A < H
  • 1 ≦ B < W

思路分析:

组合计数

首先简化问题,我们先计算一个矩形,从左上角走到右下角的路径数。

//手动忽略渣图,灵魂小画手qwq
从左上角走到右下角一共需要走H-1+W-1=H+W-2步,这其中,要选H-1步往下走,W-1步往右走。
所以组合数就是C(H+W-2,H-1)=C(H+W-2,W-1)(这两个任选其一进行计算)


可是这道题有一部分是“禁区”,怎么办呢?
有两种解决办法

1

我们可以先计算出整个矩形的方案数,再减去不合法的方案数。
不合法的方案数怎么找呢?
只要进入了“禁区”,方案就不合法(废话!
而因为只能向右或向下,所以要进入“禁区”的方案都经过了“禁区”的最上面一排。所以我们我们在到达边界的时候就要亮起红灯(嘀嘀嘀)枚举边界上那一排点,把经过了它们的方案数全部剔掉。
Like this:(有颜色的部分是“禁区”)

如图,从红点到绿点,到黄点再到蓝点的方案数必须剔掉。
注意了,每个绿点只能走它下面的那个黄点。为什么?
如果不走下面,它就不会到达“禁区”。

那为什么要用两排点?
看下面(这是我无数次不得其解的血泪史qwq):

Notice:下面这张图是不合法的!!!
必须要走到上一行再走它的下一行,直接这样会导致重复!!!(啊啊啊,我再这里卡了很久啊)
举个栗子,如果像下图那样计算,从红点到绿点1,再从绿点1到蓝点时,会有一些方案是从绿点1经过绿点2的;然后后面来计算红点到绿点2,再从绿点2到蓝点时,就会重复!!!(红点到绿点2的路径也可以经过绿点1)

所有从红点走到绿点,再从绿点走到蓝点的方案都不合法

那如果在这个图下面加一排黄点呢?干嘛非要让绿点在H-A排?就像现在这样在H-A+1排也可以吧?(啊喂你是十万个为什么吗)
答案是不行!
如果那样的话,会少一些情况:就是只经过了第一排“禁区”的情况。
比如说这个:

那搞定了所有的“十万个为什么”之后,下面来计算一下方案数:
上面的那个矩形一共走H-A+i-2,向下走,下面的那个矩形一共走A-1+W-i,向下走A-1
所以就是:

ans-=C(H-A+i-2,H-A-1)*C(A-1+W-i,A-1)
2

我们可以把这个矩形进行拆分,把它变成两个矩形,把“禁区”排斥在外,将2个小矩形的方案数相乘。拆分时枚举“断点”
Like this:

其它的都跟上面那一种是一样的。
这两种思维模式的不同在于:一个是求出所有方案数,减去不合法的(有点容斥的意味),另一个是直接求合法方案,把不合法的摒除在外。

那这一部分的方案数的计算
上面的小矩形,总步数是H-A+i-2,向右走i-1,下面的小矩形,总步数是A+W-i-1,向下走A-1步。

乘法逆元

以上,这道题的大部分地方就ok啦,但是还有一个头疼的东西。
就是这道题要mod 10^9+7
(P.S. 写#define MOD 最好后面跟 1000000007,1e9+7有时候有点玄学)
而我们知道,组合数是有除法的,而且还是阶乘的除法,而模运算对于除法没有封闭性
所以绕了这么多,还是要搞乘法逆元啊qwq
这是我第一次碰见乘法逆元的题,东西就顺便写在这儿吧。

逆元的定义

什么是逆元呢~~(搜狗输入法居然没有逆元这个词组(自动跳出来))~~

继承数学老师的衣钵,逆元的定义是关系类的定义,不会说谁是逆元,而是谁和谁互为逆元,并且这个定义是在mod m下的。

逆元的求法

比较经典的就是用费马小定理,经不经典我不知道,但是我只会这一种qwq


快速幂

这个其实就比较简单了,利用了二进制来进行优化
比如我们要求2^13
朴素的算法就是将2连乘13次
而快速幂是这么做的:13的二进制是1101 那么 213=21 * 2^4 * 2^8 就只需要计算这些值就可以了 实现时用了一个累乘器,每次判断如果这个数的最右是1的话就让ans乘一下累成器
快速幂可以降到log的级别

LL 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值