競程題解筆記
拿來做些小筆記,題解用的
ATCoder ABC
ABC-450 pE
雖然題目要求$S_{10}$$^{18}$ 的l,r
但其實算到總長度超過$10^{18}$的就夠了,因為l,r最多就到$10^{18}$
因為全部字串都是1,2組成 所以我們可以先做些預處理
預處理:
$S_1$,$S_2$的長度,包含的每個字母數量,包含的字母數量的前綴和
$S_3$~$S_{88}$ 的長度及包含字母數量
分治:
由於當前字串k 由k-1,k-2組成
如果所需長度<=k-1那k-2的地方不會用到直接遞迴就好
如果> 就加上預處理的表+去k-2遞迴 cur減掉k-1的長度
1 | if(cur<=len[k-1]){ |
終止條件:
k=0時 回傳0
k=1時 回傳字串1要求字母的前綴 2同理
能求一個點的包含,就能求一個區間的包含
我們只要找R點的答案減掉L-1的答案 就可以了
ABC-451 - pE
給一張矩陣圖 判斷是不是一顆樹
因為是樹,兩點權最小的就會是樹邊,直接跑MST,
之後再用每個點跑一次BFS/DFS 一個一個核對是不是正確的距離
總複雜度 $O(N^2 logN)$
ABC-451 - pF
邊兩端點必定異色,為二分圖
只要確定一個點 其他點也確定,最小數量為 min(同色,異色)
帶權DSU d[u]為u與root的相對顏色 如果兩個根一樣,下次加邊d[u]==d[v] 那二分圖就炸了 之後可以瘋狂輸出-1
如果沒炸就看
兩個root都是同個顏色的話就可以直接兩個相加
如果兩個不同顏色代表原本v的異色就會是u的同色 所以v的異色加給u的同色 反之亦然
ABC-452 - pD
找"不包含"的 = 全部-包含的 正難則反
預處理一個nextpos陣列,在第i格最近的字母j位置
枚舉每個L 去找到他的極限R,這樣[L,R]必定包含T字串
[L,R+1]也必定包含
將這些值用n-R 可以算出以L為邊界 R從R到n這些字串都是包含T字串的S子字串
全部加起來之後用S的全部子字串減掉剛剛算出來的包含字串即可
ABC-453 - pG
1 | int node_cnt = 0; //版本數量 |
把詢問離線處理+版本樹後直接用一顆BIT處理掉
type 1的詢問 把y陣列複製到x陣列
-> x陣列的版本改成y陣列的版本
type 2的詢問 把x陣列的第i格改成v
-> 延伸x當前版本 創造新節點(node_cnt++) 並將資訊放在邊上 接在x當前版本後面
type 3的詢問 queries[x的當前版本] pushback一個詢問
dfs運作:
1 | void dfs(int u){ |
進入當前版本時 先回答所有詢問
之後再利用當前版本的邊上的資訊 修改 點,值
回朔完後再把 點,值 改回去
ATCoder AWC
AWC-0029 - pE
題目敘述:
給定一張圖n點m邊 n<=300,m<=n(n-1)
再給s,k k為目的地點
求從s開始走全部k個地點再走回s的最小距離
N<=300 , k<=15
反射動作TSP ,n<=300距離就用floyd-warshall找最小
1 | dp[mask][i] //定義為 走過mask的點最後停在i上的最小距離 |
ans求法:
把每個u,fullmask枚舉出來
1 | int full = (1<<k)-1; |
要先枚舉u再枚舉v 而且要判斷u有沒有在mask裡
AWC-0034 pE
N<=16還是反射TSP (雖然想了有點久
定義dp[mask][u] 為放mask最後停在u的最大值
1 | 轉移式: |
其中 cur為mask所包含的1個數
每次轉移時 從每個mask裡面原有的1(u) 轉移至mask裡面有的0(v)
AWC-0038 pD
總共答案為 $C \sum _{i=1} ^n w_i$
C 就是從挑 ⌊N/2⌋ 人開始,一路加到挑滿 N−1 人的所有組合數總和:
$C =\sum _{k=\lfloor N/2 \rfloor} ^{N-1} \pmatrix{N-1\k}$
優化:
N為偶數時
剩下的人為N-1 是奇數
總共選擇的方法數為 $C = {2^{N-1} \over 2}$ = $2^{N-2}$
當N為奇數:
剩下的N-1人是偶數。
除了對稱的右半邊,我們要加總的範圍還剛好跨過了最中間的那一項 $\binom{N-1}{(N-1)/2}$。
包含了一半的總和,再補上中間項的一半。
$$C = 2^{N-2} + \frac{\binom{N-1}{(N-1)/2}}{2}$$
AWC-0038 pE
因為N<=40 選擇用折半枚舉
先枚舉左邊每個子集的容量(如果會衝突直接跳過)
之後做SOS DP
對於每個i 如果mask有i 則把i取消跟原本的取max
因為i從小往上跑,大集合裡的小集合已經會是最佳答案了
$O(N⋅2^{N/2})$
之後再枚舉右半
只要枚舉的集合是合法的,則把會與裡面點衝突的左半點關掉,直接去拿剛剛dp完的數值,相加與答案取max
最後輸出答案要再對M取min
AWC-0042 pE
定義R[i]為第i天選擇休息的最大金額
W[i] 為第i天選擇工作的最大金額
每次轉移時 思考"上次做不同的選擇是甚麼"
算工作就找 上次最大的選擇休息休息金額
算休息就找 上次最大的選擇工作金額
滑窗找極值->單調對列優化
計算上次工作到今天休息的金額:
連續陣列相加->前綴和
Sprout-2026
w3 - 染色遊戲
O(N) 的解:
枚舉t 0~n
計算每個矩形的面積,兩兩矩形的交集
1 | //面積計算: |
然後去排容排一下就有答案了
w3 - 樹重心
寫這題的時候忘記怎麼求了(x
總之就是對於每個點 找子樹最大值(函向上子樹)不超過n/2的點
都是樹重心
CodeForces
ECR 118 - pE
觀察到 S(x) 會是 頭+尾
head 為x 尾是u由x的數位和(sum of digit)所遞迴形成的
不變量: 字串的總和不變
假設x的數位和是Y 知道Y就可以知道後面的"尾巴"部分是甚麼了
Y+ digitsum(尾) = total
接下來就是模擬 尾巴的形成
再計算總共的sum是不是跟total一樣
如果sum=total 再檢查字數有沒有一樣
都一樣的話就可以輸出答案了