有个表叫杨表(下)
《浅谈杨氏矩阵在信息学竞赛中的应用 袁方舟》膜拜有感
前方高能,非战斗人员请撤离(都是很干的数学概念)
钩子公式
对于一个杨图 \(\lambda\) 来说,一个方格的钩子 (hook) 函数等于它正右边方格数量 + 正下边方格数量 + 1,记为 \(h_\lambda(x,y)\)。
举个 \(\alpha\) 粒子,杨图 \(\lambda=(4,2,2,1)\) 中,\((1,1)\) 方格右边和下边各有 \(3\) 个方格,加上自身总共 \(7\) 个,即 \(h_\lambda(1,1)=7\)。另外还有 \(f_\lambda(2,1)=4\),其他懒得写了。
给定杨图 \(\lambda\),钩子公式可以告诉我们形状为 \(\lambda\) 的标准杨表有多少个。钩子公式如下:
很简单,就是 \(n\) 的阶乘除以所有方格的钩子函数之积。为了写代码方便,钩子公式有第二个形式:
基于这个公式,上代码!
int calc(vector<int> &a, int n) { // 阶乘 fact, 阶乘倒数 invfact 要自己写
int m = a.size();
long long ans = 1;
for (int i = 0; i < m; i++)
for (int j = i + 1; j < m; j++)
(ans *= a[i] - i - a[j] + j) %= mod;
for (int i = 0; i < m; i++)
(ans *= invfact(a[i] + m - i - 1)) %= mod;
(ans *= fact(n)) %= mod;
(ans += mod) %= mod;
return ans;
}
这题结合了 LIS 和钩子公式(状压 dp 也可以,但是钩子公式更快)(注意排列和两个标准杨表对应,不要漏了平方),可以测测板子
但是但是但是,这个算法 \(O(m^2)\) 的鸭,能不能再给力一点?
能。
把钩子公式改成 \(f_\lambda=n!\dfrac{\prod_{1\le i<j\le m}(r_i-r_j)}{\prod r_i!},r_i=a_i+m-i\),考虑数组记录 \(r_i\) 出现的次数,如果 \(x\) 在 \(r\) 中出现了记 \(A[x]=1\),否则 \(A[x]=0\)(\(x\) 肯定只出现一次),用 FFT 可以算出 \(C[k]=\sum_{i-j=k} A[i]A[j]\),\(\prod_{1\le i<j\le m}(r_i-r_j)\) 就等于 \(\prod_{i=1}^{n} i^{C[i]}\)
上代码!(只提供了 \(\prod_{1\le i<j\le m}(r_i-r_j)\) 的计算)
const int nn = 1000010; // 比 n 大就行
long long A[N], B[N], r[N];
ll solve(ll a[], int m) {
for (int i = 0; i < nn * 2; i++) A[i] = B[i] = 0;
for (int i = 1; i <= m; i++) {
r[i] = a[i] + m - i;
A[r[i]] = 1;
B[nn - r[i]] = 1;
}
long long ans = 1;
ntt::conv(A, B, nn * 2, A);
for (int i = 1; i < nn; i++)
if (A[i + nn]) (ans *= qpow(i, A[i + nn])) %= mod;
// 这里还要乘以 n! 除以 prod r[i]!
return ans;
}
这题就是带FFT的钩子公式的例题
以上,阳间的杨表已经介绍完毕了。
接下来是阴间的杨表。
杨图的随机游走
这部分袁老师讲错了,我找了原论文但是没看懂(菜),最后还是靠猜。不过这部分没什么用就是了。
给定一个杨图,初始随机出现在杨图任一位置(每个位置概率 \(\tfrac 1 n\)),然后每次操作都可以往右走任意格或往下走任意格(每个位置概率 \(\tfrac 1 {h_\lambda(x)}\)),则走到边角 \((r,s)\) 概率为:
另外还有带权的版本,每行权重 \(x_i\),每列权重 \(y_j\),初始随机出现在杨图某一位置(概率权重 \(x_iy_j\)),向下走到某位置的概率权重为目标行的权重,向右为列的权重,则走到边角 \((r,s)\) 概率为:
oh 这里概率权重指的是,进行某个操作的概率等于这个操作的概率权重除以所有可行的操作的概率权重。
写在这里就当给论文纠错吧。
斜杨表和不相交网格路径
约定坐标系中 \(x\) 轴正方向是右,\(y\) 轴正方向是上。
网格中从整点 \(S(x_0,y_0)\) 走到整点 \(T(x_1,y_1)\),每次只能往右或上走一个单位,那么方案数为 \(P(S,T)=\displaystyle\dbinom{x_1-x_0+y_1-y_0}{x_1-x_0}\)。
一个斜半标准杨表 \(\lambda/\mu\),每个数字值域 \([1,z]\),则 \(\lambda/\mu\) 可以表示为 \(m\) 条不相交路径 \((\mu_i-i,1)\rightarrow (\lambda_i-i,z),i=1\ldots m\)。
这意味着,我们在斜半标准杨表与不相交网格路径之间建立了一一对应关系,套用 LGV 引理,斜半标准杨表的个数就可以写出来了:
如果要考虑斜标准杨表,这意味着要把 \(\sum(\lambda_i-\mu_i)\) 个纵坐标分配给各个路径,一通我也看不懂的操作(好像是行列式的定义),得到:
注:\(\dfrac{1}{a!}\) 在 \(a<0\) 时等于 \(0\)。
代入 \(\mu_i=0\) 可以得到标准杨表个数的另外一个公式,因为没钩子公式好用,就不放在这了。
斜杨表计数好像没题目可刷,难受。只能拿出论文里的题目了。
Euler numbers
长为 \(2n\) 的排列中,计算满足 \(a_1 < a_2 > a_3 < \ldots > a_{2n-1} < a_{2n}\) 的方案数。
恰好对应了 \((2n-1 + 2, 2n-2 + 2, \ldots , n + 2)/(2n-1, 2n-2, \ldots , n)\) 的斜标准杨表,就是长得像楼梯一样的形状。然后就用公式。
但是,这个欧拉数 A000364 是有 \(O(n \log n)\) 算法的。具体咋搞论文好像没说。
(时隔多日我滚回来了,只要展开指数型生成函数 sec(x) 就行了。)
半标准杨表与 k-Dyck Path
没错,喜闻乐见的一一对应关系又来了。这次出场的是会斜着走的 \(k\) 个人,每个人都从 \((0,0)\) 走到 \((2n,0)\),只能在第一象限走,只能往右上和右下方向走,而且要求编号小的路径在编号大的路径上方。
看懂是不存在的,直接拿来主义。
列数不超过 \(2k\) 的,元素都在 \([1, n]\) 内的且每行大小为偶数的半标准杨表和长度均为 \(2n + 2\) 的 k-Dyck Path 形成双射关系,且计数公式如下:
考虑下面的数严格大于上面的数,行数自然是有限的。
半标准杨表与对称单调矩阵
我们考虑一个元素都在 \([1, n]\) 内,列数不超过 \(k\) 的半标准杨表。它的个数被证明和 \(n\times n\) 的元素在 \([0, k]\) 内的对称矩阵满足每行每列都非严格递增的数量相同。
好家伙袁老师也不会证。(并不)
半标准杨表计数
这里袁老师用了对称多项式和交错多项式等操作来证明。oh 不管了。
总结
论文有 28 页,我看了足足一个星期,看到后面更是不求甚解,抄个公式就走,最后几个公式甚至连验算都没验,实在是水平有限。
杨表确实是个精妙的结构,学了那么久,我也不敢说我学会了多少。不过至少还是有点成就感的。