Loading

格路计数

最简单的问题:

\((0,0)\) 开始,只能往上或往右走,问有多少种方案可以走到 \((n,m)\)

注意到一共 \(n+m\) 步,必须向上走 \(m\) 步,向右走 \(n\) 步,所以方案数为 \({n+m\choose m}\)

卡特兰数:

\((0,0)\) 开始,只能往上或往右走,不经过直线 \(y=x+1\),问有多少种方案可以走到 \((n,n)\)

我们考虑容斥,算出经过直线 \(y=x+1\) 而且到达 \((n,n)\) 的方案数。

我们找到第一次经过 \(y=x+1\) 的那个点,将后面的折线沿 \(y=x+1\) 翻折过去,终点变成了 \((n-1,n+1)\),我们发现这样的构造的映射是一个双射,可以把每一种不合法方案和 \((0,0)\to(n-1,n+1)\) 的方案构成双射,所以不合法方案就是 \({2n\choose n-1}\),所以我们就可以得到卡特兰数的公式为 \(H_n={2n\choose n}-{2n\choose n-1}\)

我们将这种技巧叫做反射容斥。

再扩展一点点:

\((0,0)\) 开始,只能往上或往右走,不经过直线 \(y=x+b\),问有多少种方案可以走到 \((n,m)\)

类似地,我们找到第一次经过 \(y=x+b\) 的那个点,将后面的折线沿着 \(y=x+b\) 翻折过去就会得到与不合法方案的一组双射,终点对称过去得到 \((m-b,n+b)\),可以得到答案为 \({n+m\choose n}-{n+m\choose m-b}\)

两条线的格路计数:

\((0,0)\) 开始,只能往上或往右走,不经过直线 \(y=x+l\)\(y=x+r\),问有多少种方案可以走到 \((n,m)\)

首先,若 \(l,r\) 同号就相当于一条线的格路计数用上面的方法就行了。

\(l,r\) 异号,我们仍然考虑容斥,找到第一次经过直线的那个点,将后面的折线翻折,但是我们发现这样并不是双射,如果这个路径两条直线都经过了,那么会算重,所以考虑继续容斥将答案加上两条直线都经过的方案数。

两条直线都经过可以分为先经过 \(y=x+l\) 再经过 \(y=x+r\),或者反过来,简写为 \(\text{LR}\)\(\text{RL}\),但是这样直接算也会算重,还要继续容斥,减去 \(\text{LRL}\)\(\text{RLR}\) 的答案,这样一直容斥下去就可以得到正确答案,即:

\[ans=f(\varnothing)-f(\text L)-f(\text R)+f(\text{LR})+f(\text{RL})-f(\text{LRL})-f(\text{RLR})+\cdots \]

注意,这里重复经过一条直线算一次。

其中 \(f(s)\) 表示路径经过两条直线的点的前缀为 \(s\) 的方案数,这个可以用反射容斥做,这个是双射,化简后最终答案是:

\[ans=\sum_k\left({n+m\choose n-k(r-l)}-{n+m\choose n-k(r-l)+r}\right) \]

虽然这个 \(k\) 取遍所有整数,但是使得组合数不为 \(0\)\(k\) 只有 \(O(\frac{n+m}{r-l})\) 个,我们可以对这个做根号分治。

另一个做法:

把坐标系顺时针旋转 45 度,就变成了两条水平的线,每次只能往右上或右下走,设两条线为 \(y=0\)\(y=b\),你需要从 \((0,a)\) 走到 \((n,m)\)

这其实就相当于求出一个整数序列相邻项的差的绝对值为 \(1\),且每个数要在 \([0,b)\) 的范围内的方案数。

一个巧妙的 trick,考虑镜像法,写出序列 \([0,1,2,\cdots,b,b-1,b-2,\cdots,1]\),并把它接成环,那么每一次移动就是在环上左右移动,没有边界限制了,这就可以直接用 \((x+1/x)^n\bmod x^{2b}\) 计算方案数。

posted @ 2026-02-05 11:58  liruixiong0101  阅读(46)  评论(0)    收藏  举报