1. 程式人生 > >退役前的做題記錄1

退役前的做題記錄1

noi 包含 ESS 取出 icpc pan class contest ioi

學習一波鴿子的更博方式

Transforming Sequence

\(f_{i,j}\) 表示前 \(i\) 個,選了 \(j\) 個二進制位
\(f_{i,j}=\sum f_{i-1,k}2^k\binom{j}{k}\)
倍增+\(MTT\) 即可

Kyoya and Train

\(f_{i,j}\) 表示 \(i\)\(n\) ,時間為 \(j\) 的最小期望代價
\[f_{u,j}=min(w_{u,v}+\sum f_{v,j+k}p_{(u,v),k})\]
對於時間分治 \(+FFT\) 即可
復雜度 \(O(mTlog^2T)\)

Perpetual Subtraction

首先顯然有一個 \(dp\)\(f[i][j]\) 表示前 \(i\) 輪之後為 \(j\) 的概率
那麽 \(f[i][j]=\sum_{k\ge j}\frac{f[i-1][k]}{k+1}\)
不會線性代數,不會矩陣
設生成函數 \(F_i(x)=\sum_{j} f[i][j]x^j\)
那麽
\[F_{i+1}(x)=\sum_{j} x^j\sum_{k\ge j}\frac{f[i][k]}{k+1}=\sum_{k}\frac{f[i][k](x^{k+1}-1)}{(k+1)(x-1)}\]
\[=\frac{1}{x-1}\sum_{j}\int_{1}^{x}f[i][j]t^jdt=\frac{1}{x-1}\int_{1}^{x}F_i(t)dt\]


\(G_i(x)=F_i(x+1)\)
那麽
\[G_{i+1}(x)=\frac{1}{x}\int_{0}^{x}G_i(t)d(t)\]
展開就是
\[G_{i+1}(x)=\frac{\sum_jg[i][j]x^{j+1}}{(j+1)x}=\sum_{j}\frac{g[i][j]}{j+1}x^j\]
那麽也就是 \(g[i+1][j]=\frac{g[i][j]}{j+1}\)\(g[m][j]=\frac{g[0][j]}{(j+1)^m}\)
現在考慮 \(f\)\(g\) 的關系
\[G(x)=F(x+1)\]
\[\rightarrow \sum_{i}g[i]x^i=\sum_{i}f[i](x+1)^i=\sum_{i}f[i]\sum_{j\le i}\binom{i}{j}x^j=\sum_{i}\sum_{j\ge i}\binom{j}{i}f[j]x^i\]

也就是
\[g[i]=\sum_{j\ge i}\binom{j}{i}f[j]\]
那麽二項式反演之後就是
\[f[i]=\sum_{j\ge i}(-1)^{j-i}\binom{j}{i}g[j]\]
這兩個東西都可以拆開之後 \(NTT\)

仙人掌計數

\(n\) 個節點無重邊、自環,有標號的仙人掌個數
\(C(x)\) 為其指數級生成函數
可以考慮把它分成若幹個部分,然後 \(exp\) 起來
那麽可以欽定一個點刪掉,也就是弄個根
\(F(x)\) 為有根仙人掌個數的生成函數
顯然有 \(F_i=iC_i\)
考慮刪掉根之後的圖長成什麽樣子
對於與根不在一個環上的相鄰節點,就會變成以該點為根的仙人掌,生成函數為 \(F(x)\)
對於與根在一個環上的相鄰節點,把這個環拆開,變成以環上的點為根的仙人掌,由於還可以翻轉,那麽生成函數為 \(\sum_{i\ge 2}\frac{F^i(x)}{2}\)
把這些東西 \(exp\) 起來,即
\[e^{\frac{2F(x)-F^2(x)}{2-2F(x)}}\]
加上刪去掉的根,即
\[F(x)=xe^{\frac{2F(x)-F^2(x)}{2-2F(x)}}\]
對這個東西牛頓叠代求解 \(F(x)\) 即可
註意由於 \(F_0=0\),沒有辦法對它求 \(ln\)

生成樹計數

推導:
根據 \(prufer\) 序列,答案顯然就是
\[\sum_{\sum_{i}d_i=2n-2}(n-2)!\prod_{i=1}^{n}\frac{a_i^{d_i}d_i^m}{(d_i-1)!}(\sum_{i=1}^{n}d_i^m)\]
\[=(n-2)!(\prod_{i=1}^{n}a_i)\sum_{\sum_{i}d_i=n-2}\frac{a_i^{d_i}(d_i+1)^m}{d_i!}(\sum_{i=1}^{n}(d_i+1)^m)\]
後面那個 \(\sum_{i=1}^{n}(d_i+1)^m\) 可以看成是做 \(n\) 次求和,每次欽定一個連通塊的貢獻為多乘上一個 \((d_i+1)^m\)
考慮生成函數
\(F(x)=\sum_{i}\frac{(i+1)^m}{i!}x^i,G(x)=\sum_{i}\frac{(i+1)^{2m}}{i!}x^i\)
那麽答案變成
\[(n-2)!(\prod_{i=1}^{n}a_i)[x^{n-2}]((\sum_{i=1}^{n}\frac{G(a_ix)}{F(a_ix)})\prod_{i=1}^{n}F(a_ix))\]
先考慮計算 \(\prod_{i=1}^{n}F(a_ix)\)
\[\prod_{i=1}^{n}F(a_ix)=exp(\sum_{i=1}^{n}ln (F(a_ix)))=exp(\sum_{i=1}^{n}(lnF)(a_ix))\]
(復合函數的結合律)
那麽只要求 \(\sum_{i=1}^{n}(lnF)(a_ix)\)
而又要求 \(\sum_{i=1}^{n}\frac{G(a_ix)}{F(a_ix)}=\sum_{i=1}^{n}(\frac{G}{F})(a_ix)\)
也就是考慮這樣一個問題
已知 \(f_i,a_i\)\(\sum_{i=1}^{n}\sum_{j}f_ja_i^jx^j\) 的每一項系數
也就是要求 \(\forall j,\sum_{i=1}^{n}a_i^j\),然後對應位置相乘
即要求 \(\sum_{i=1}^{n}\frac{1}{1-a_ix}\) 的每一項系數
\[\sum_{i=1}^{n}\frac{1}{1-a_ix}=\frac{\sum_{i=1}^{n}\prod_{j\ne i}(1-a_jx)}{\prod_{i=1}^{n}(1-a_ix)}\]
下面的可以分治 \(FFT\),上面的也可以分治計算,\(O(nlog^2n)\)
所以此題復雜度 \(O(nlogn+nlog^2n+nlogm)\) 其中 \(nlogm\) 為快速冪

新年的小黃鴨

\(f_u\) 表示選完了 \(u\) 的子樹的答案
枚舉 \((u,v)\) 一條重鏈,轉移貢獻為 \(\sum_{x\in (u,v)} (\lceil log_2dis(x,u) \rceil +1)+\sum_{x\in subtree_u,x\notin (u,v)}f_v+size_v\)
後面的 \(\sum\) 很好維護,主要是前面的
直接把貢獻拆分成 \(log\) 個,分 \(log\) 次加入,用一個 \(nlog_2n\) 的數組把每個點掛在它的 \(2^i\) 的祖先上
只需要在一棵線段樹修改+查詢即可

「ROI 2017 Day 2」學習軌跡

首先如果只在一個學校上課的話,答案顯然就是選擇所有的課程。
否則在兩個學校上課,不難證明至少有一所學校上課的權值和必定大於其所有權值和的一半 (否則不如在某一個學校上課)。
對於權值做前綴和,假設 \(THU\) 的前綴和是 \(S_a\) ,\(PKU\) 的前綴和是 \(S_b\), 不難證明只要超過了一半,必定會選擇前綴和第一次 \(\frac{1}{2}S_a\)\(\frac{1}{2}S_b\) 的位置。
不妨先隨便令一所學校要跨過中位數。比如說 \(THU\) 吧。
那麽顯然答案就是在 \(PKU\) 的課程中隨意選擇一段,然後把重復的課程在 \(THU\) 的課表中標記出來,然後從中位數開始向兩側拓展,能走就走。
那麽設 \(f[l][r]\) 表示選擇了 \(PKU\)\([l, r]\) 這一段的答案,那麽枚舉右端點用線段樹動態來維護這個東西。
貢獻顯然是 \(S_b[r] ? S_b[l ? 1] + S_a[R] ? S_a[L ? 1]\)
因為是從 \(mid\) 位置開始,向左右兩側拓展。
那麽我們枚舉右端點之後,兩側分別維護一個單調隊列。
首先因為枚舉了 \(r\),所以 \(S_b[r] ? S_b[l ? 1]\) 很容易計算,現在問題就在於如何維護 \(S_a[L, R]\)
在單調隊列加入當前位置和彈掉當前位置的時候,會影響一段區間的貢獻,在線段樹上修改即可。

[IOI2017]Wiring

模擬費用流
拆點,一個權值為 \(-\infty\),容量為 \(1\),另一個權值為 \(0\),容量為 \(\infty\)
因為兩側都有了容量為 \(\infty\) 的點,所以我們要重新分析一下復雜度。
如果是第一類點 \(a\) 匹配了左邊某一個點 \(b\) ,則 \(b\) 不可能反悔。因為 \(a\) 是必須匹配的, \(b\) 一旦反悔,a 和 \(b\) 將同時連往 \(a\) 右邊的點,匹配交叉,矛盾
如果是第二類點 \(a\) 匹配了左邊某一個點 \(b\) ,則 \(b\) 一定是第一類點。因為 \(b\) 是必須匹配的,所以 a 一旦反悔, \(a\)\(b\) 將同時連往 \(a\) 右邊的點,匹配交叉,矛盾
所以,每次匹配完之後,只有一方可能反悔。增廣總次數不超過 \(2n\)

雪災與外賣

遇到一只老鼠時,老鼠可能會先匹配之前的堆,然後往老鼠堆中丟一個這只老鼠反悔的操作。
這個過程放到本題,堆操作總次數依然是線性。
當遇到一個洞時,洞可能會匹配一大堆老鼠,即從老鼠堆中取一大堆元素。然後洞和老鼠都有可能反悔,這樣要同時往老鼠堆和洞堆中丟元素。
每次一個洞匹配了若幹個老鼠之後,往老鼠堆中丟的元素都是等權的。這樣我們就只需要在堆中對每個元素記錄一下出現的次數,堆的操作總次數就變成了線性。

看代碼清晰的多QwQ

if (!hole.empty()) {
    ans += (v = -hole.top().first + x[i]);
    id = hole.top().second, mouse.push(make_pair(x[i] + v, 0));
    hole.pop();
    if (id) hole.push(make_pair(y[id], id));
    while (!hole.empty() && -hole.top().first + x[i] < 0) {
        ans += (v = -hole.top().first + x[i]);
        id = hole.top().second, hole.pop();
        hole.push(make_pair(x[i], 0));
        if (id) hole.push(make_pair(y[id], id));
    }
}
else ans += inf, mouse.push(make_pair(x[i] + inf, i));
mouse.push(make_pair(x[i], i));

「ICPC World Finals 2018」征服世界

\(lca\) 處考慮,模擬費用流,維護兩個可並堆即可

PA2014Final Krolestwo

對於二分圖,從 \(X\) 交替走回到 \(X\) 部的路徑長度一定是偶數。
沿用歐拉路做法,建一個點 \(Root\),把 \(Root\) 與度數為奇的點連邊。
然後考慮把點 \(u\) 拆成兩個點 \(u、u'\) ,把原圖改造成二分圖。
改造後:
原圖邊 \((u, v)\) 對應 \((u, v′)\) 或者 \((v, u′)\) 中的一條。
每個點的度數為偶數。
如果能做到上述轉化,跑歐拉路即可得解。
因為每個點度數為偶,即不存在脫離的邊,所以一定能跑出解。
轉化方法?
首先先一頓亂連,把二分圖整出來。
顯然若保證左側度數都為偶數,那麽右側一定度數都為偶數。
然後跑原圖的一棵生成樹,自底向上不斷調整即可。

Counting Sheep in Ami Dongsuo

\(f_{u,i,j}\) 表示 \(u\) 號點,選了 \(j\) 個終點,權值和為 \(i\) 的方案數
建反圖跑一邊即可預處理
最後對於每一個 \(i\)\(f_{u,i,3}\) 加起來就是答案
直接做是 \(O(81mw^2)\) 的,代入 \(w+1\) 個點求點值,最後插值即可
復雜度 \(O(27mw+9w^2)\)

珍珠遊戲

很好的一道題目
首先第一個想法就是設 \(f_i\) 表示 \(w_i\) 貢獻的期望次數
那麽 \(ans=\sum f_iw_i\)
怎麽求 \(f_i\)
這個題目就妙在這裏,把包含 \(i\) 的塊拆成前面和後面(美妙的期望的線性性)
\(g_i\) 表示一個長度為 \(i\) 的塊,它的首部貢獻的期望次數
那麽 \(f_i=g_i+g_{N-i+1}-1\),多算了所以要 \(-1\)
\(g_i\) 很好算,\(g_i=\sum_{j\le i} \frac{1}{j}\),即每個位置在前所有位置之前取走的概率

Egor and an RPG game

可以發現 \(f(n) = k ? 1\),其中 \(k = min\){\(x|\frac{x(x+1)}{2}> n\)}。
考慮證明同時構造答案。
對於長度為 \(n\) 的序列,設其 \(LIS\) 長度為 \(len\)
\(len \le K\), 則 \(n ? len < \frac{K(K+1)}{2}-K=\frac{K(K-1)}{2}\)
\(len < K\), 根據 \(Dilworth\) 定理,可以用 \(< K\) 個下降序列覆蓋, 只需要把以 \(i\) 相同的長度的點分成一組即可
ps:Dilworth\(DAG\) 中的最小鏈覆蓋數等於其最長反鏈
在這裏就是最長上升序列長度等於最少下降序列的覆蓋

新年的Dog劃分

先構出一棵生成樹,判斷是否是二分圖只要在這個生成樹中看一下有沒有同奇偶性深度的邊(奇環)即可
怎麽構造一棵生成樹?
考慮從一個點開始每次找出一條與它相連的邊
一個比較好的方法就是 \(BFS\),把已經在生成樹裏面的不在隊列中的點到任意點的非樹邊全部去掉
當沒有加入的點有若幹個只與當前點連通時擴展,這樣的點的存在性可以判斷,找到這樣的點可以二分

【UER #8】打雪仗

通信題
對於 \(task1\) 直接 \(Alice\) 返回所有,\(O(2n)\)
對於 \(task2\) 可以分成兩部分,詢問多一半直接 \(Alice\) 返回,少的 \(Bob\) 詢問,\(O(n+\frac{n}{2})\)
對於 \(task3\) 可以分成三部分,詢問多的 \(\frac{1}{3}\) 直接 \(Alice\) 返回,少的 \(Bob\) 詢問,\(O(n+\frac{n}{3})\)

New Year and Finding Roots

首先如果一開始就找到了一個葉子,那麽暴力去遞歸找它的父親,每次隨機一個方向(除了已知的兒子)走深度次,如果走到了一個葉子就不是這個方向
(設根的深度為 \(1\))這樣子最後到達深度為 \(3\) 的點需要花費 \(11\)
註意到此時只有與該點距離不超過 \(2\) 的點可能是根,這樣的沒有詢問過的點不超過 \(6\)
所以只要詢問 \(5\) 次,一共 \(16\)
如果一開始不是葉子,那麽嘗試 \(dfs\) 到一個葉子,最後再套用上面的做法
註意每次隨機一個方向的時候要判斷之前是否已經有一條長度為深度的鏈(也可以優先選擇詢問過的點)

Compressed Spanning Subtrees(H)

首先可以 \(O(n)\) 找出所有的葉子
為了保證得到祖先關系,選擇某個葉子為根
這樣可以求出每個葉子的所有祖先
將它的祖先按照 \(size\) 排好序,一個個接上去就可以得到這棵樹了(因為不存在度數為 \(2\) 的點)
詢問次數 \(O(\frac{n^2}{4})\)

Build a Palindrome

枚舉長的那個的回文串即可。\(PAM+SAM+hash\) 亂搞。

[Cerc2012]Farm and factory

設新加入的點為 \(x\)\(d\) 為新的距離,\(a,b\) 分別為原圖中到 \(1,2\) 的距離,那麽就有一些限制
\(d_{x,i}+d_{x,1}\ge a_i\)
\(d_{x,i}+d_{x,2}\ge b_i\)
而根據最短路,又有一些限制
\(d_{x,1}\le d_{x,i}+a_i\)
\(d_{x,2}\le d_{x,i}+b_i\)
可以得到
\(d_{x,i}\ge max(|d_{x,1}-a_i|,|d_{x,2}-b_i|)\)
顯然是可以達到 \(max(|d_{x,1}-a_i|,|d_{x,2}-b_i|)\)
現在的問題在於怎麽確定 \(d_{x,1},d_{x,2}\) 的值
不難發現上面的 \(max\) 就是一個切比雪夫距離的形式,直接弄成曼哈頓距離即可。
分別取出中位數就是答案。

pfs

\(min25\) 第二部分的時候強行計一個最大的指數即可。

Ribbons on Tree

容斥+樹形 \(DP\),轉移加個容斥系數就沒了。

LJJ 的字符串

枚舉兩個前綴的距離計算,差分一個二次函數即可,類似 [NOI2016]優秀的拆分。

Most Dangerous Shark

預處理出每個點向右和向左能擴展到哪裏,\(l_i,r_i\)
一個性質就是擴展的區間要麽包含,要麽相離。
\(f_i=min(f_{j-1}+c_j(j < i \le r_j),f_{l_i-1}+c_i)\)
單調棧處理 \(l,r,f\) 即可。

YJC plays Minecraft

\(f_i,g_i\) 分別表示 \(i\) 個點的樹和森林的個數,\(F,G\) 為其指數生成函數,顯然 \(G(x)=e^{F(x)}\)
為了計算答案,再設 \(h_i\) 表示 \(i\) 個點,\(1,n\) 在同一個連通塊的方案數。
那麽 \(h_{i}=\sum_{j=0}^{i-2}g_jf_{i-j}\binom{i-2}{j}\),顯然可以寫成卷積的形式。
最後 \(ans=2^n\prod_{i=1}^{n}g_{a_i}-\prod_{i=1}^{n}h_{a_i}\)
以上用多項式各種運算即可實現。

退役前的做題記錄1