有个表叫杨表(上)

《浅谈杨氏矩阵在信息学竞赛中的应用 袁方舟》膜拜有感

前方高能,非战斗人员请撤离(都是很干的数学概念)

前言

杨表 (Young tableaux),又叫杨氏矩阵,是一个啥都能掺一脚的代数结构。

为了方便讨论,先来点定义。

杨图:令 \(\lambda = (\lambda_1,\lambda_2,\ldots,\lambda_m)\) 满足 \(\lambda_1\ge\lambda_2\ge\ldots\lambda_m\ge 1,n=\sum \lambda_i\)。一个形状为 \(\lambda\) 的杨图是一个表格,第 \(i\) 行有 \(\lambda_i\) 个方格,其坐标分别为 \((i,1)(i,2)\ldots(i,\lambda_i)\)。下图为 \(n=9,\lambda=(4,2,2,1)\) 的杨图。

\[\left[\begin{array}{c} * & * & * & * \\ * & * \\ * & * \\ * \end{array}\right] \]

半标准杨表:将杨图填上数字,满足每行数字单调不减,每列数字单调递增。

标准杨表:将 \(1,2,\ldots,n\) 填入杨图,满足每行、每列数字单调递增。下图为 \(n=9,\lambda=(4,2,2,1)\) 的一种标准杨表。

\[\left[\begin{array}{c} 1 & 4 & 7 & 8 \\ 2 & 5 \\ 3 & 9 \\ 6 \end{array}\right] \]

斜杨图:令 \(\lambda = (\lambda_1,\lambda_2,\ldots,\lambda_m),\mu=(\mu_1,\mu_2,\ldots,\mu_{m'})\),则形状为 \(\lambda/\mu\) 的斜杨图为杨图 \(\lambda\) 中扣去杨图 \(\mu\) 后剩下的部分。下图为 \((9, 7, 5, 1)/(5, 3, 2)\) 的斜杨图。

\[\left[\begin{array}{c} \cdot & \cdot & \cdot & \cdot & \cdot & * & * & * & * \\ \cdot & \cdot & \cdot & * & * & * & * \\ \cdot & \cdot & * & * & * \\ * \end{array}\right] \]

斜半标准杨表、斜标准杨表:猜都猜得到,不浪费时间了。

杨表的插入操作 / RSK 算法

RSK 算法包括了插入和删除。删除操作其实就是插入反过来,不影响理解杨表就不写了。

想要插入 \(x\) 时,从第一行开始,在当前行中找最小的比 \(x\) 大的数字 \(y\) (upperbound)(其实大于 \(x\) 还是大于等于 \(x\) 要看具体情况),交换 \(x,y\),转到下一行继续操作;若所有数字比 \(x\) 小则把 \(x\) 放在该行末尾并退出(如果超出了杨图的行数,那么杨图行数加 \(1\)

举个 \(\alpha\) 粒子,将 \(3\) 插入下图半标准杨表:

\[\left[\begin{array}{c} 1 & 3 & 3 & 5 \\ 2 & 6 \\ 4 \end{array}\right] \begin{array}{c}\leftarrow 3\\\\\\\end{array} \]

第一行找到 \(5\),变成:

\[\left[\begin{array}{c} 1 & 3 & 3 & 3 \\ 2 & 6 \\ 4 \end{array}\right] \begin{array}{c}\\\leftarrow 5\\\\\end{array} \]

第二行找到 \(6\),变成:

\[\left[\begin{array}{c} 1 & 3 & 3 & 3 \\ 2 & 5 \\ 4 \end{array}\right] \begin{array}{c}\\\\\leftarrow 6\\\end{array} \]

第三行找不到比 \(6\) 大的数字,放到末尾:

\[\left[\begin{array}{c} 1 & 3 & 3 & 3 \\ 2 & 5 \\ 4 & 6 \end{array}\right] \]

可以证明这样操作后仍然满足半标准杨表的定义。

上代码!

vector<int> a[N];
void insert(int x) {
	for (int i = 0;; i++) {
		auto it = upper_bound(a[i].begin(), a[i].end(), x);
		if (it == a[i].end()) {
			a[i].push_back(x);
			return;
		}
		swap(x, *it);
	}
}

杨表与 LIS

LIS (Longest Increasing Subsequence) 就是广为人知的最长上升子序列(有时是不下降)。杨表之所以能和 LIS 有关,是因为杨表的插入操作,只看其中一行的话,正好是 dp 求 LIS 的算法。(虽然这是废话)

拓展一下,如果要求 \(k\) 个不相交的 LIS,它们的长度之和最大为杨图前 \(k\) 行长度之和,即 \(\lambda_1+\lambda_2+\ldots+\lambda_k\)。不过要注意,杨表前 \(k\) 行并不能告诉我们 LIS 有哪些数。(类似 dp 求 LIS 后那个 dp 数组也无法告诉我们 LIS 有哪些数)

举个 \(\alpha\) 粒子,如果把 \([1,5,3,2,6,7,4]\) 插入到杨表中得到:

\[\left[\begin{array}{c} 1 & 2 & 4 & 7 \\ 3 & 6 \\ 5 \end{array}\right] \]

显然 \(1,2,4,7\) 不是 LIS,LIS 应该是 \(1,5,6,7/1,3,6,7/1,2,6,7\)。不过长度是相同的。

这题就是求 k-LIS 的题了。但是 \(k\) 没有限制,如果维护的杨表行数太大,朴素的插入算法 \(O(n^2 \log n)\) 肯定过不了。这就需要一个杨表的性质:如果把比较运算反过来(大于变小于等于),插入操作后的杨图和原来的杨图是转置关系(但是杨表和杨表不是转置的,只是形状转置),具体可以看看这题的题解。

话说回来,由于杨表和转置杨表的关系,我们可以得出一个结论,如果杨表的第一行数字个数是最长上升子序列长度,那么第一列数字个数是最长不上升子序列长度。如果某题限制了最长上升子序列长为 \(\alpha\),最长不上升子序列长为 \(\beta\),我们就可以把它和行数为 \(\alpha\),列数为 \(\beta\) 的杨表联系起来。(现在还没用,一一对应的关系在下文会讲)

杨表与排列

我们可以将排列的数字按顺序插入到空杨表中,这样就会得到一个标准杨表。但是这会出现两个排列对应一个杨表的情况,比如排列 \([2,1,3]\) 和排列 \([2,3,1]\) 都会得到杨表 \(\left[\begin{array}{c}1 & 3 \\ 2 \end{array}\right]\),出大问题。

考虑一个排列对应两个杨表,每插入一个数字到杨表 \(A\),我们在杨表 \(B\) 对应位置记录这个数字的下标(下标从 \(1\) 开始)。

可以证明 \(B\) 也是个标准杨表。

举个 \(\alpha\) 粒子,对于排列 \([2,3,1]\),插入 \(2\) 得到:

\[A=\left[\begin{array}{c}2 \end{array}\right], B=\left[\begin{array}{c}1 \end{array}\right] \]

插入 \(3\) 得到:

\[A=\left[\begin{array}{c}2 & 3 \end{array}\right], B=\left[\begin{array}{c}1 & 2 \end{array}\right] \]

插入 \(1\) 得到:

\[A=\left[\begin{array}{c}1 & 3 \\ 2 \end{array}\right], B=\left[\begin{array}{c}1 & 2 \\ 3 \end{array}\right] \]

\([2,1,3]\) 会得到:

\[A=\left[\begin{array}{c}1 & 3 \\ 2 \end{array}\right], B=\left[\begin{array}{c}1 & 3 \\ 2 \end{array}\right] \]

这样,我们就把一个排列和两个标准杨表一一对应了起来。

杨表和对合排列

对合排列是一种特殊的排列,把对合排列当成个置换后,自己乘自己等于单位置换。好理解一点就是 a[a[i]]=i

比如 \(\left[\begin{array}{c}1 & 2 & 3 \\ 2 & 1 & 3\end{array}\right]\) 就是个对合置换。

为什么要讲对合排列呢,因为把对合排列对应的两个标准杨表是相等的。这意味着一个对合置换和一个杨表是一一对应的关系。

上篇只是个无聊的铺垫,在下篇中我会好好讲钩子公式和其他组合数学相关内容的。

下篇

posted @ 2021-02-02 01:14  axiomofchoice  阅读(1270)  评论(0编辑  收藏  举报