前言:又上頭了
T1
賽時做法:首先,假設對答案做出貢獻的是點x,y,設y的祖先且為x的兒子的點為z,那麼顯然,把除了z以外的所有都歸入集合是最優的,因為這不會影響對y的統計且儘量滿足了限制
於是就列舉點x
但這時,我不會了,我知道啟發式合併可以做,但我不會(忘了),於是我想線段樹合併,事實證明,還是有點難寫的,碼量上了5k,還另外寫了一顆線段樹來維護距離一個點最遠的點
然後被卡常了
正解:還是考慮上面的轉化,但用dfs序轉化成序列後用雙指標,然後看滿足有K種顏色的最小區間,並和當前點的子樹或除了當前點的子樹的所有點的區間比較然後更新即可
T2
簡單題,首先貪心的思路是顯然的,每次選最大c[i]個操作
然後考慮快速維護這個過程,考慮減1的性質,就是減後交換一部分割槽間
於是考慮序列平衡樹,每次平衡樹查詢後劃分成4個區間,然後按序合併即可
T3
一道挺有難度且很有意思的題
首先,考慮當前的i和目標j,起點陣列為a
假設\(a[i]<a[j]\),那麼每次跳到下落速度更快的一定更優,因為如果在這個位置換,到目標線段的時間一定優於不換,大於就改成下落速度更慢的,類似,於是只考慮第一種
那麼最優策略一定是一個類似凸包的軌跡
考慮從上往下掃起點,用單調棧,如果當前的與棧頂沒交點就彈
如果當前的和次棧頂的相交時間比棧頂更早,那麼就彈
記錄當前點的下一個點,設為dw
那麼對於每個i,一直跳dw即可,這樣是\(n^2\)的
考慮最佳化,用倍增的思想,把dw看做父親,就可以倍增跳然後跳到父親與目標更優的最右的點,然後跳到父親,最後求交點,沒有交點就無解
T4
一道挺有難度且很有意思的題
首先,可以從任意一個點開始,等待一段時間後全部收掉,這是不劣於走兩圈的
考慮環,直接段環成鏈即可,那麼對於i,設從s時刻開始走,那麼可得不等式:\(s+(j-i)>=T_j\),移項可得\(s>=(T_j-j)-i\),那麼s最大就是右邊的最大,總時間應再加上n-1即可
那麼可得答案式子:\(\min_{i=1}^n(i+\max_{j=i}^{i+n-1}(T_j-j))+n-1\)
首先,內層的j的列舉範圍可以改成\(n\times 2\),因為多出來的j原來的j-n也有,且j比j-n大,所以一定不優
於是就轉化成了一個近似固定的形式,由於帶修,所以考慮線段樹
設\(minn[i]\)表示線段樹節點i的左子樹的答案,因為我們倍長了陣列,\(maxn[i]\)表示線段樹節點i的\(T_j-j\)的最大值
建樹,修改簡單,於是我們考慮如何更新
首先,maxn的更新是簡單的,但minn可能由於右子樹的改變而改變,於是我們遞迴左子樹並考慮當前的右子樹的maxn(設為mmax)對左子樹中的節點的影響
分類討論:1,為葉子,那麼就直接考慮不更新和用mmax更新的優劣
2,當前的右子樹的maxn更劣,那麼右子樹中所有答案都無效,則右子樹的答案就是\(mid+1+mmax\),但不知道左子樹的情況,於是遞迴左子樹
3,當前的右子樹更優,那麼左子樹不會改變,於是遞迴看右子樹的優劣
這樣就完成了更新,然後統計答案即可,時間複雜度\(O(n\log^2n)\)
——————————————————————————————————————————————————————————————————————————————
下次加油!!!