2024年11月隨便做做

saubguiu發表於2024-11-18

十月太擺了沒有隨便做做環節。

測試題目選集

20241102 - D. 有理數

相當於求:

\[\prod_{1\le i<j\le n} \frac{b_ib_j}{\gcd (b_ib_j,b_ia_j-b_ja_i) } \]

為了方便書寫,記 \(a\leftarrow b_i,b\leftarrow a_i,c\leftarrow b_j,d\leftarrow a_j\)。實際上就是對 \(\gcd (ac,ad-bc)\) 做分析。

首先,應該有 \(\gcd (a,b)=\gcd (c,d)=1\),否則可以先自己化簡自己。之後考慮這一個式子實際上是有積性(對於 \(a,c\) 而言)的,因此對於每個素數 \(p\) 單獨考慮。記 \(a=a'p^{k_1},b=b'p^{k_2}\),同時要求 \(a'\nmid p,b'\nmid p\),當然應該有 \(k_1,k_2>0\)

如果 \(k_1\ne k_2\),則不妨令 \(k_1<k_2\),那麼原式就是 \(\gcd (ac,ad-bc)=p^{k_1}\gcd (a'c'p^{k_2-k_1},a'd-bc'p^{k_2-k_1})\)。發現 \(\gcd(a',p)=1,\gcd(d,p)\le \gcd (d,a')=1\),同時因為 \(k_2-k_1>0\),所以 \(bc'p^{k_2-k_1}\)\(p\) 的倍數。因此 \(a'd-bc'p^{k_2-k_1}\not\equiv 0 \mod p\),因此對於 \(p\) 來說貢獻就是 \(p^{k_1}\)

否則,記 \(k=k_1=k_2\),則先提出 \(p^k\),剩餘 \(\gcd(a'c'p^k,a'd-bc')\)。而在只考慮 \(p\) 的貢獻下,就應該是:

\[\begin{aligned} &\prod_{k'=1}^k p^{[a'd-bc'\equiv 0\mod p^{k'}]} \\ =&\prod_{k'=1}^k p^{[\frac{b}{a'}\equiv\frac{d}{c'}\mod p^{k'}]} \end{aligned} \]

以上所有的情況都可以用桶實現。其中一種容易想到的實現的時間複雜度是 \(O(V\log_2 V+n\log_2^2 V)\)

20241106 - D. 牛仔

實際上比較簡單,關鍵實際上是轉化成非牛仔序列之後對於每個出現的匹配的計算方案數。同時可以注意到每個數是等價的,所以用 \(A\) 去匹配時,只需要乘 \(\frac{(k - pre)!}{k!}\) 就行了,其中 \(pre\)\(A\) 中最長的字首使得沒有重複的數。

20241106 - D. 盼君勿忘

給定一棵樹。每個點有顏色 \(0\)\(1\)。每次將樹上相鄰且顏色相同的兩個點的顏色同時改變,記 \(s_i\)\(i\) 的初始顏色,\(t_i\) 為最終顏色,\(f(s,t)\) 為顏色序列 \(s\) 變為 \(t\) 的最少運算元,無法做到則為 \(0\)。現在某些 \(s_i,t_i\) 上為 ?,表示顏色未知。求對於所有可能的 \(s,t\)\(f(s,t)\) 之和對 \(10^9+7\) 取模。

\(n\le 5\times 10^5\)

首先感覺要求相鄰且相同的點同時變色的條件非常令人沒有頭緒。這時在樹上有一個很棒的轉化,就是將奇數深度的點的顏色全部取反。這樣操作之後,原本的條件變成了交換兩個相鄰不相同的點的顏色,當然因為有運算元最小的要求,實際上就是交換兩個相鄰點的顏色。所以操作後,\(s_i\leftarrow s_i \oplus [2\nmid dep_i]\)\(t_i\) 同理。當然 ? 不需要管。

然後放一放題目,將這一系列操作變得簡單可理解:從初始狀態 \(s\) 開始,每次其實就是移動一個顏色為 \(1\) 的點,移動到 \(t_i=1\) 的點上和其抵消。然後做一下經典等價變換,相當於是 \(s_i=1\)\(t_i=1\) 黑白兩種棋子,棋子只能往上移,黑白棋子碰在一起會抵消。這樣似乎就變得明朗多了,記 \(z_u=|\sum_{v\in subtree(u)} s_u-t_u|\),會發現答案實際上就是 \([z_1=0]\sum_{u} z_u\),因為可以合併的一定在子樹內抵消完了,往上走的一定是未被抵消的棋子,於是對每個 \(u\to father_u\) 的邊計算貢獻即可。然後就可以解決已知 \(s,t\) 的情況了。值得注意的是必須要有 \(z_1=0\) 的條件,不止是因為合不合法的問題,這一步其實也是後續的關鍵。

\(s\) 中問號個數為 \(A\)\(t\) 中為 \(B\),已知部分的 \(\sum_u s_u-t_u=C\)。考慮對於一個子樹 \(u\) 計算 \(z_u\) 的貢獻,在其中的 \(s_v\) 為問號的個數為 \(x\)\(t_v\) 為問號的個數為 \(y\),子樹內已知部分的 \(\sum_{v\in subtree (u)} s_v-t_v=z\)

那麼可以列舉 \(i,j,k,l\) 分別為子樹內外 \(s,t\) 中問號為 \(1\) 的個數。那麼 \(u\) 對答案的貢獻為:

\[\sum_{i\le x}\sum_{j\le y}\sum_{k\le A-x}\sum_{l\le B-y}[C+i-j+k-l=0]{x\choose i}{y\choose j}{A-x\choose k}{B-y\choose l}|z+i-j| \]

進行一步不太顯然的轉化,考慮列舉 \(p=i-j,q=k-l\) 來代換:

\[\begin{aligned} &\sum_{i}\sum_{p}\sum_{k}\sum_{q}[C+p+q=0]{x\choose i}{y\choose i-p}{A-x\choose k}{B-y\choose k-q}|z+p| \\ =&\sum_{i}\sum_{p}\sum_{k}\sum_{q}[C+p+q=0]{x\choose x-i}{y\choose i-p}{A-x\choose A-x-k}{B-y\choose k-q}|z+p| \\ =&\sum_{p}\sum_{q}[C+p+q=0]{x+y\choose x-p}{A+B-x-y\choose A-x-q}|z+p| \\ =&\sum_{p}{x+y\choose x-p}{A+B-x-y\choose A-x+C+p}|z+p| \end{aligned} \]

最後一步因為 \(C+p+q=0\) 的緣故可以將原式轉化成一個可以 \(O(n)\) 計算的式子。所以得到了一個 \(O(n^2)\) 的做法。

考慮進一步最佳化:記 \(P=x-p,X=A+B,Y=A+C\),有代換:

\[\begin{aligned} \sum_{P}{x+y\choose P}{X-x-y\choose Y-P}|z+x-P| \end{aligned} \]

到這裡似乎就明朗多了,實際上每個 \(u\) 求的是一個類似的的多項式。記 \(f(x,y)=\sum_{i}{x\choose i}{X-x\choose Y-i}|y-i|\)。那麼答案實際上是 \(\sum_{u} f(x_u+y_u,z_u+x_u)\),其中 \(x_u,y_u,z_u\) 對應上文對於 \(u\) 求貢獻一節的 \(x,y,z\)

\(f(x,y)\) 進行適當的改寫:

\[\begin{aligned} f(x,y)=&\sum_{i}{x\choose i}{X-x\choose Y-i}|y-i| \\ =&\sum_{i}{x\choose i}{X-x\choose Y-i}(i-y)+2\sum_{i\le y}{x\choose i}{X-x\choose Y-i}(y-i) \\ =&-y {X\choose Y}+x\sum_i {x-1\choose i-1}{X-x\choose Y - i}+2\sum_{i\le y}{x\choose i}{X-x\choose Y-i}(y-i) \\ =&-y {X\choose Y}+x{X-1\choose Y-1}+2\sum_{i\le y}{x\choose i}{X-x\choose Y-i}(y-i) \end{aligned} \]

前面可以 \(O(1)\) 計算,將後面單獨提出來:

\[\begin{aligned} &\sum_{i\le y}{x\choose i}{X-x\choose Y-i}(y-i) \\ =& y\sum_{i\le y} {x\choose i}{X-x\choose Y-i}-x\sum_{i\le y}{x-1\choose i-1}{X-x\choose Y- i} \\ =& y\sum_{i\le y} {x\choose i}{X-x\choose Y-i}-x\sum_{i< y}{x-1\choose i}{X-x\choose Y-1- i} \end{aligned} \]

前後本質上都是另一個多項式 \(g(X,Y,x,y)=\sum_{i\le y} {x\choose i}{X-x\choose Y-i}\)。於是可以把其替換為 \(y\cdot g(X,Y,x,y)-x\cdot g(X-1,Y-1,x - 1,y-1)\)

因為本質上求法是一樣的,所以在下文中將用 \(g(x,y)\) 代表實際上的 \(g(X,Y,x,y)\)

但是 \(g(x,y)\) 仍然並不好求。這時可以考慮計算 \(g(x+1,y)-g(x,y)\)\(g(x,y+1)-g(x,y)\) 的值,前者考慮組合意義得出,而後者十分顯然。

\[g(x+1,y)-g(x,y)={x\choose y}{X-(x+1)\choose Y - (y+1)} \\ g(x,y+1)-g(x,y)={x\choose y+1}{X-x\choose Y-(y+1)} \]

於是可以由 \(g(x,y)\) 得到 \(g(x,y+1)\)\(g(x+1,y)\)

然後可以使用莫隊做到 \(O(n\sqrt n)\)

而有一個更優的做法,就是重鏈剖分之後對每個鏈單獨計算,因為重鏈鏈上的是同階的所以時間複雜度為 \(O(n\log_2 n)\)。這裡重鏈剖分實際上應該對 \(x_i+y_i,z_i+x_i\) 做,但是因為限制嚴格小於二倍子樹大小,所以直接重剖 size 就可以了。

Miscellaneous

[AGC022D] Shopping

神秘題目,比較酷。

首先發現對於 \(t_i\ge2L\)\(t_i\) 可以直接將 \(t_i\lfloor\frac{t_i}{2L}\rfloor\) 加入答案並將 \(t_i\)\(2L\) 取模。然後只考慮 \(t_i \ne 0\)\(i\)

考慮如何最佳化這個策略。首先簡化操作,如果從一個點出來之後往某個方向走到最邊上之後折返回來經過這個點,那麼選擇在後面上車。因此得到了好像更簡單的操作序列。之後在操作序列中將花 \(2L\) 時間的點去掉之後,會發現每次從一個點出來一定會改變方向,這個序列(如果存在的話)一定是第一次會往左走時進,往右走時出,最後一次和第一次的方向一定相反,這個序列長度為偶數,貢獻為長度除以 \(2\) 乘以 \(2L\),因為實際上是第 \(2i-1\) 個和第 \(2i\) 個配對最佳化一個 \(2L\)。這啟發出了更進一步,將(可以左走變右走的點)和(可以右走變左走的點)進行儘量多的配對,因為每個配對可以最佳化一個 \(2L\)。似乎是一個很難的問題。

這時構建一種思路,對於每個 \(i\),直接花 \(2L\) 的時間走,這樣時間就是 \(2L\cdot (n + 1)\) 的。之後對於剩餘的每個非 \(0\) 的位置,記 \(l_i= [2x_i\ge t_i]\) 表示車下了人之後往左走再回來是否可以直接接上,\(r_i\) 同理。\(l_i=1\) 說明可以右走變左走,\(r_i\) 同理。實際上我們就是找 \(i<j,l_i=r_j=1\),最大的不交 \((i,j)\) 對數,因為透過一些思考得到對於 \(\{(i,j)\}\) 一定存在 \(|\{(i,j)\}|=|\{(i',j')\}|\)\(\{(i',j')\}\) 可以拼出一個順次的操作序列。

考慮觀察性質:

  • \(l_i=r_i=0\) 時,無法最佳化。

  • \(l_i=1,r_i=0\) 時,\(2x_i\ge t_i > 2L - 2x_i\),得到 \(x_i\ge L/2\)

  • \(l_i=0,r_i=1\) 時,同理可得 \(x_i\le L/2\)

  • \(l_i=r_i=1\),可以隨便匹配。

於是發現 \(l_i+r_i=1\) 的匹配一定是和 \(l_j=r_j=1\) 的合併,而 \(l_i=r_i=1\) 的也可以自己合併,於是分開貪心匹配就可以了。

有個小細節是,\(n\) 一定存在一種最優操作序列使得它不會被匹配,因為若 \(r_n=1\) 可以自己少一次 \(2L\)

Submission #59511721 - AtCoder Grand Contest 022

NIKKEI Programming Contest 2019 F - Jewels

題意:每個物品有顏色和權值,每個顏色要麼不選,要麼至少選兩個,對 \(i=1,\cdots,n\) 分別求出選恰好 \(i\) 個的最大權值。

將每個顏色中前兩大的放在一起,權值取平均數,稱為對子,剩餘的稱為單個,從大到小排序之後求答案 \(f(x)\)。如果字首恰好可以拼出 \(x\),那麼就直接是答案。

重點就是拼不出 \(x\) 的時候,發現一定可以拼出 \(x-1\),那麼剩餘不能放進去的是一對。然後直覺上似乎已經放進去的 \(x-1\) 中取出來的數不會很多。先嚐試分類討論:

  • 不去掉數,加入之後一個合法的(自己顏色對應的對子已經被加入)對子已經加入的單個。
  • 去掉一個之前的單個。此時後面可以加入兩個合法單個或者加入一個對子。但是顯然加入兩個單個是不優於對子的,因為 \((x,x+1)\) 處的對子一定大於兩個它後面的單個之和。所以策略應該是去掉單個之後直接加入 \((x,x+1)\) 處的對子。
  • 去掉兩個數。一種情況是去掉兩個單個之後加入一個對子以及一個合法單個,但是這個合法單個顯然小於等於去掉的兩個單箇中的任意一個,所以一定不優於直接去掉一個加上一對的策略。另一種策略就是去掉一個對子,加入一個對子和一個合法單個,注意到這個單個實際上必須和加入的對子同色,否則因為合法,所以必定時原本 \(x-1\) 裡邊的某個對子的單個,因此可以不用刪去對子,直接加入這個單個即可。因此策略應該是去掉一個對子,加入同色的對子和單個。
  • 去掉三個數。首先去掉三個單個的情況可以參考去掉兩個單個的情況,明顯不優。所以只剩下去掉一個對子加上一個單個的情況。加入四個單個同樣明顯不優。考慮加入一個對子和兩個單個同樣不優,因為如果要加對子那麼就先將單個去掉,這是就變成了前面的對子替換後面兩個單個,明顯不優。那麼只剩下加入兩個對子。考慮這樣同樣不優,同之前一樣先去掉一個單個,加入一個對子,這時剩下的操作就是去掉一個對子再加入一個對子,顯然不優。

透過去掉三個數的情況似乎發現了一些性質。如果去掉的集合裡邊有單個而加入的集合中有對子,那麼可以去掉這個單個再加入對子。之後的替換就變成了相同數量的交換,一定不優於不換(如果加入集合還有剩餘)。如果加入集合只有這個對子,情況在分類討論中已討論。那麼就剩下去掉的集合中全為對子或者加入的集合中全為單個的情況。

加入的集合中全為單個的情況,發現加入集合的大小不會超過 \(1\),因為隨便加入一個合法的單個之後,剩餘部分實際上是等量的前後替換,明顯不優。

去掉的集合中全為對子的情況,如果加入集合中存在一個對應對子在 \(x-1\) 前面的位置,那麼顯然可以變成只加入這個單個,明顯不優。否則就是新加入了某些顏色的一個對子和若干對應單個,首先如果某個顏色的單個大於等於兩個一定不如保留去掉集合中的對子。其次如果存在沒有單個的對子,也可以替換成前面的對子。再其次如果(對子+單個)的數量大於等於 \(2\),就可以去掉兩個這種形式,保留三個去掉集合中的對子。所以就只剩下去掉集合中只有一個(對子+單個)的情況,這在上文的分類討論中已經講過了。

因此可以發現策略只有三種:

  • 加入一個合法的單個。
  • 去掉一個單個,加入 \((x,x+1)\) 處的對子。
  • 去掉一個對子,加入一個對子和同種顏色的一個單個。

有很多資料結構都可以維護這個。

Submission #59932152 - NIKKEI Programming Contest 2019

相關文章