GP of Southeastern Europe 2021
D. LIS Counting
給定 \(n,m\),以及模數 \(p\)。考慮所有滿足 \(LIS=n,LDS=m\) 的排列,定義 \(f(pos,val)\) 表示滿足 \(p_{pos}=val\) 的排列個數。
你需要對於 \(1\le pos,val\le nm\) 均求出答案。
\(1\le n\cdot m\le 100,10^8\le p\le 10^9\),\(p\) 為質數。
Solution
考慮一個排列 \(p\),記二元組 \((inc_i,dec_i)\) 表示前綴 \(i\) 的 LIS 和 LDS,我們放置兩個楊表 \(A,B\),在 \(A_{inc_i,dec_i}\) 位置插 \(i\),\(B_{inc_i,dec_i}\) 位置插 \(p_i\),最終形成的楊表必定是 \(n\times m\) 的。
容易發現這是雙射,即我們固定一組 \(A,B\),一定能得到 \(p\) 且 \(p\) 滿足要求。
我們觀察 \(A,B\) 楊表的性質。對於 \(A\) 而言,有行列均遞增;對於 \(B\) 而言,有行遞減,列遞增。因此 \(A,B\) 楊表本質相同,下面我們只考慮計數 \(A\)。
我們記 \(A\) 的第 \(i\) 行長度為 \(a_i\),顯然有 \(m\ge a_1\ge a_2 \ge \cdots \ a_m\ge 0\),於是 \((a_1,a_2,\cdots,a_m)\) 這個 \(m\) 元組有 \(\binom{n+m}{m}\) 種可能,我們可以爆搜得到楊表的所有形態。
接下來,我們用 \(dp[i][state]\) 表示在楊表里放了 \(1\sim i\),當前楊表的形態是 \(state\) 的方案數,轉移是平凡的。
考慮答案怎么求,對於 \(f(pos,val)\) 而言,答案是 \(\sum\limits_{i,j} coef_A[i][j][pos] \times coef_B[i][j][val]\),其中 \(coef\) 數組表示有多少個楊表的 \((i,j)\) 位置等於 \(pos\),該數組是好求的。
總時間復雜度 \(\mathcal O(\binom{n+m}{n} m^2 +(nm)^3)\),在 \(n=12,m=8\) 的時候最卡。
評測記錄,這題超級沒有素質,連個過的代碼都沒有。。
I. Colourful Permutation Sorting
給定排列 \(p_1,p_2,\cdots,p_n\),每個位置有一個顏色 \(c_i\),一共有 \(k\) 種顏色。
現在,你可以做任意多次以下兩種操作:
- 花費 \(S\) 的代價,交換任意兩個數;
- 花費 \(cost_i\) 的代價,隨便排列顏色 \(=i\) 的位置的數。
你需要用最小的代價使得排列滿足 \(p_i=i\),求代價。
\(1\le n\le 10^5,1\le k\le 5\)。
Solution
首先,我們抽象這個問題:
有 \(n\) 個盒子,第 \(i\) 個盒子編號為 \(i\)。有 \(n\) 個球,第 \(i\) 個球編號為 \(i\)。
初始第 \(i\) 個盒子里放着第 \(p_i\) 個球。
- 1 操作:交換第 \(i\) 個盒子里的球和第 \(j\) 個盒子里的球;
- 2 操作:隨便交換顏色 \(=i\) 的盒子。
容易發現 1 操作和 2 操作是獨立的,因此我們可以先執行 1 操作,最后再執行 2 操作,並且每種顏色至多進行一次操作 2。
於是我們 \(O(2^k)\) 枚舉哪些顏色進行了操作 2,給每個選的顏色開一個點,答案就是 選的顏色代價和 + \(S\times (n-環數)\),我們目標是最大化環數。問題轉化為一張 \(5\) 個點的有向圖最多能分解成幾個環。
我們不妨先去除自環和二元環,因為如果 \(i\to j,j\to i\) 不在一個環里,我們調整它們所在的兩個環,答案不劣。
假如圖只有 \(4\) 個點,那么由抽屜原理知,總出度 \(\le \binom{4}{2}\),因此必定存在一個點出度為 \(1\),即經過這個點的環必定走這條出邊,因此我們直接把該點和出邊縮起來,問題降到 \(3\) 個點的子問題。
現在圖有 \(5\) 個點,可能會出現一個點的出度 \(=2\),此時它的入度至多為 \(2\)(因為入度 + 出度 + 1 \(\le 5\)),由於總邊數是 \(O(n)\) 量級的,我們暴力枚舉其中一條出邊的訪問情況,問題又轉化為 \(4\) 個點的子問題。
時間復雜度 \(\mathcal O(2^k (n + \text{poly}(k)))\)。
M. Many LCS
構造兩個 01 串 \(S,T\),滿足它們的公共子序列數 \(=K\)。
\(1\le K\le 10^9\),你需要滿足 \(1\le |S|,|T|\le 8848\)。
時間限制 \(\text{4000ms}\),空間限制 \(\text{256MB}\)。
Solution
一種很新穎的 idea(感謝 @YLWang 的指導):
我們構造 \(S=\underline{00..0}\ 01\ \underline{00..0}\ 01 \cdots \underline{00..0}\ 01\),其中有 \(m\) 段,第 \(i\) 段的 \(00..0\) 個數為 \(a_i\);\(T=01\ 01\ \cdots 01\),其中有 \(n+m\) 個 \(01\)。滿足 \(\sum a_i \ge n\)。
我們要讓它們的 LIS 做到 \(n+2m\),即 \(S\) 中的 \(01\) 均取,然后每段中取 \(0\le b_i\le a_i\) 個 \(0\),滿足 \(\sum b_i=n\)。顯然,對於不同的 \(b\) 取法,對應不同的最長 LIS。
對於合法的 \(b\) 序列計數,我們可以考慮容斥哪些 \(b_i> a_i\) 來計算。但為了方便,我們不妨假設 \(a_i>\frac{n}{2}\),這樣就不存在至少兩個 \(b_i\) 爆限制的情況,方案數就簡化為:
當我們取 \(m=4\) 的時候,這里的五個組合數基本上可以遍歷 \(0\sim 10^9\) 的所有數。因此我們找到最小的 \(n\) 滿足 \(\binom{n+m-1}{m-1}\ge k\),然后用 01 背包找出 \(a_1\sim a_4\) 即可。如果當前 \(n\) 不滿足,我們試試看 \(n+1\),依次類推,這里的移動次數極少。
但是存在一個問題:我們需要滿足 \(a_i > \frac{n}{2}\),當 \(k\) 較小時 \(n\) 也較小,可能導致構造不出解。
幸運的是,當 \(k\) 較小的時候,我們取 \(m=2\),構造 \(S=\underline{00..0}\ 01\ \underline{00..0}\ 01\),\(T=01\ 01 \cdots 01\),\(S\) 中每段 \(0\) 的個數為 \(k-1\),\(T\) 中的 \(01\) 的個數為 \(k+1\) 即可。
