1. 程式人生 > >Codeforces Round #453 (Div. 1)

Codeforces Round #453 (Div. 1)

class 一個數 test 運算 nom 除了 min 有一個 存在

Codeforces Round #453 (Div. 1)

A. Hashing Trees

題目描述:給出一棵樹的高度和每一層的節點數,問是否有兩棵樹都滿足這個條件,若有,則輸出這兩棵樹,否則輸出perfect

solution
首先判斷什麽時候是perfect:當不存在相鄰兩層的節點數均大於\(0\)時,輸出perfect
接下來就是構造的問題。若上一層只有一個節點,那麽這一層的所有節點只能連到那個唯一的節點,否則分為兩棵樹不同的構造:

  1. 所有點都連到上一層的第一個節點
  2. 第一個點連到上一層的第一個節點,其它點連到上一層的第二個節點。

時間復雜度:\(O(n)\)

B. GCD of Polynomials

題目描述:將求兩個數的公因數的輾轉相除法拓展到求兩個多項式的公因式上去。給定一個數\(n\),求兩個多項式,使得該多項式的系數的絕對值小於等於\(1\),且運用了\(n\)步輾轉相除。

solution
手工計算前幾項可以發現:
\[p_0=1, p_1=x\]
\[p_{n+1}=xp_n \pm p_{n-1}\]
是加號還是減號需要判斷一下,但總有一個符號能滿足條件。最終的答案就是\(p_n, p_{n-1}\)

時間復雜度:\(O(n^2)\)

C. Bipartite Segments

題目描述:給定一個有\(n\)個點的無向圖,滿足圖中沒有長度為偶數的環。有\(q\)個詢問,每次詢問給定一個區間\([L, R]\)

, 問有多少個子區間\([x, y], (L \leq x \leq y \leq R)\), 使得只包含\([x, y]\)的點和它們之間的邊的子圖是二分圖。

solution
由題目條件可以看出,該圖是一棵頂點仙人掌,而且圖中的環的長度都是奇數,又因包含奇環的圖都不是二分圖,所有由區間\([x, y]\)構成的圖不能有環。

首先找出每個環中編號最大值和最小值,以此來求出對於每個點\(i\),最大的\(Rmax[i]\)使得\([i, Rmax[i]]\)沒有環,這個從大到小掃一下就好了。對於每個詢問,答案為\((\sum min(Rmax[i], R)-i+1)\),由於\(Rmax[i]\)

是遞增的,所以可以二分求出最大的\(j\),使得\(Rmax[j] \leq R\)\([L, j]\)可由部分和求出,後面的直接用求和公式就好。

時間復雜度:\(O(qlogn)\)

D. Weighting a Tree

題目描述:給定一個無向連通圖,每個點都有一個值\(c_i\)\(c_i\)的奇偶性與\(i\)的度相同,現給每條邊添加一個邊權,使得每個點所連的邊的邊權之和等於\(c_i\),求一種方案或無解。

solution
考慮兩種情況:

  1. 該圖是一個二分圖。如果二分圖的兩邊的\(c_i\)之和不同,則無解,否則隨便找出一棵生成樹,令不在樹上的邊權為\(0\)。隨便找一個點為根,然後從葉子節點開始給邊賦值即可。
  2. 該圖有奇環。隨便找出一個奇環,然後整個圖隨便找一棵生成樹,令不在樹上的邊權為\(0\)。隨便找一個在之前找的奇環裏的點為根,然後從葉子節點開始給邊賦值。最終有可能根的\(c_i\)是不滿足的(滿足的話直接輸出答案即可),記當前與根相連的邊權和為\(sum\)。找出在環中的與根相連的邊,將該邊的權值加\(x\),然後沿著奇環將邊權\(-x,+x,-x, ..., +x\)交替運算,其中\(x=\frac{c_i-sum}{2}\)(這裏一定能整除)。這樣除了根,在環中的點所連的邊的邊權總和不變,而與根相連的總和增加了\(c_i-sum\),使得根滿足條件。

時間復雜度:\(O(n)\)

E. Cyclic Cipher

題目描述:現有一個方法來加密一個長度為\(n\)的序列\(a_i\),為加密這個序列,我們會選擇一個密鑰\(b_i(0\leq i<n)\)\(b_i\)有一個特點,那就是它每一個循環置換的數組都是線性無關的,也就是說,不存在一組非零系數,使得\(\sum_{i=0}^{n-1} x_ib_{(k-i)mod(n)}=0\)對於所有的\(k\)都成立。加密過程為:
\[c_i=\sum_{k=0}^{n-1}(b_{(k-i) mod (n)}-a_k)^2\]
現給出\(c_i,b_i\),求出所有滿足的\(a_i\)

solution
觀察\(c_i, c_{i-1}\):
\[c_i=\sum_{k=0}^{n-1}(b_{(k-i) mod (n)}-a_k)^2\]
\[=\sum_{k=0}^{n-1} (b_{(k-i) mod (n)}^2 - 2a_kb_{(k-i) mod (n)} + a_k^2)\]

\[c_{i-1}=\sum_{k=0}^{n-1}(b_{(k-i+1) mod (n)}-a_k)^2\]
\[=\sum_{k=0}^{n-1} (b_{(k-i+1) mod (n)}^2 - 2a_kb_{(k-i+1) mod (n)} + a_k^2)\]

第一項是\(\sum b_i^2\)(兩個式子只是循環置換了而已,本質都是平方和), 第三項是\(\sum a_k^2\), 只有第二項是不一樣的。因此
\[c_i-c_{i-1}=-2\sum_{k=0}^{n-1} a_k(b_{(k-i) mod (n)} - b_{(k-i+1) mod (n)})\]
\(b‘_i=b_i-b_{i-1}, c‘_i=\frac{c_i-c_{i-1}}{2}\),則
\[c‘_i=\sum_{k=0}^{n-1} a_kb_{(k-i+1) mod (n)}\]
\(p=k-i+1\),則
\[c‘_i=\sum_{p=0}^{n-1} b‘_pa_{p+i-1}\]

\[B=\sum_{k=0}^{n-1} b‘_kx^k, A=\sum_{k=0}^{n-1}a_kx^{n-k}, C=\sum_{k=0}^{n-1} c‘_kx^k\]
\(C=AB\),符合卷積運算,用FFT就能逆推出來,但在逆推過程中會出現多解,具體可參考題解,但我覺得裏面的符號有點亂。

Codeforces Round #453 (Div. 1)