JSOI部分題解

JSOI部分題解

JSOI2018

戰爭

問題轉化爲給定你兩個凸包\(\mathbb S,\mathbb T\),每次獨立的詢問將\(\mathbb T\)中的每個點移動一個向量,問\(\mathbb S,\mathbb T'\)是否有交。
我們知道對於兩個凸包\(\mathbb {A,B}\)的閔科夫斯基和爲\(\mathbb C=\{\vec a\in\mathbb A,\vec b\in \mathbb B\;|\;\vec a+\vec b\}\)
而兩個凸包對於一次移動向量\(\vec w\)有交,則存在\(\vec a=\vec b+\vec w\Leftrightarrow\vec w=\vec a-\vec b\)
那麼構造\(\mathbb Q=\{\vec t\in \mathbb T\;|\;-\vec t\}\),構造\(\mathbb P=\mathbb{S+Q}\),每次判斷是否有\(\vec w\in\mathbb P\)即可。

列隊

可以貪心地想,將\([l,r]\)內所有人的休息點從小到大排序後依次放入\(K...K+r-l\)答案是最優的。
那麼現在問題主要轉化爲如何快速求\(\sum_{i\in [l,r]} |a_i-(K+i-l)|\)(假設\(a\)已排好序)。
這時候可以對於原序列\(\{a\}\)建主席樹維護個數及\(a\)的和,考慮拆掉絕對值的話就是二分\(mid\),表示\(a\)大小前的\(mid\)名均有\(a_i\leq K+i-1\),因爲\(a\)兩兩不同所以可以保證存在一個這樣的分界點。
直接在外面二分後用等差數列求和算答案複雜度爲\(O(n\log^2 n)\)可以獲得\(70pts\),改爲在主席樹上二分複雜度\(O(n\log n)\)可獲得滿分。

潛入行動

有一個顯然的dp是設\(f[x][i][0/1][0/1]\)表示\(x\)的子樹內安裝了\(i\)個監聽器,他自己不選/選,他父親不選/選的方案數。
轉移較爲繁瑣而且容易實現,這裏不再贅述。
考慮複雜度:乍一看複雜度爲\(O(nk^2)\)但是仔細思考發現滿足度數爲\(k\)的點最多\(\frac nk\)個,那麼最終複雜度爲\(O(nk)\)

防禦網絡

題意:求從一個仙人球中任選一個點集所構成的斯坦納樹大小的期望。
考慮每條邊的貢獻,如果一條邊不再環內的話貢獻很好算。
那麼主要問題就是解決環上的邊怎麼算貢獻,只考慮某一個環,如果一個點的子樹內選擇了點的話就把環上這個點給標記出來,那麼最後選擇的東西就一定是整個環的長度減去相鄰兩個被選中的點的最大距離。
\(f_x\)表示相鄰兩點最大長度不超過\(x\)的方案數,那麼對於一個\(x\),它的方案數就是\(f_x-f_{x-1}\)
因爲是一個環,斷環爲鏈後枚舉最左被選擇邊的點就可以消除原來環的影響。
剩下的部分考慮dp,設\(g_i\)表示當前在第\(i\)個點且強制選第\(i\)個點的方案數,轉移時強制長度差不超過\(x\)前綴和優化即可。
最終複雜度\(O(n^3)\)

絕地反擊

這裏提供兩種方法:

方法一:
是我自己想到的,對於圓上點的排列,假設所有點均由正方向旋轉度數\(\alpha\),那麼最優解函數\(f(\alpha)\)一定爲一個單峯函數。
三分\(\alpha\)後再二分時間\(t\),將到達時間\(\leq mid\)的我方艦隊向敵方母艦連邊,跑二分圖匹配看是否有完美匹配即可。
這種做法我在loj上是\(80pts\),但是經過一些常數優化後應該是可以過的。

方法二:
二分時間\(t\),那麼對於每艘戰艦在圓弧上的交點至多隻有\(2\)個,而對於旋轉,可以發現本質不同的轉法一定是有一個點轉到了這\(2n\)個交點中的其中一個。
我們將這\(2n\)個轉角極角排序(這\(2n\)個點可用餘弦定理算出),則每次改變轉角最多加入或刪除一組匹配,手動模擬退流即可,複雜度\(O(二分圖匹配\times\log n)\)

JSOI2016

最佳團體

考慮01分數規劃,那麼我們現在二分了比值\(mid\),每個點有一個新的權值\(c_i=p_i-s_i\times mid\)
現在要求在滿足條件的情況下使\(\sum c\)最大,樹形揹包即可。

獨特的樹葉

因爲是樹的同構問題,考慮樹哈希。
有一種異或的樹哈希方法(\(f\)爲哈希數組):
\[ f_i=\bigoplus_{j\in son_i} f_{j}\times seed+size_j \]
通過換根可以求出以每個點爲根的\(f\)值,將\(A,B\)樹分別哈希並將\(A\)中的每個哈希值丟到set中,如果有\(B\)中有一個葉節點的父親去掉(xor)對應葉節點的\(f\)值後這個哈希值不在這個set中,說明對應的葉節點就是那個多餘的點。

扭動的迴文串

單獨存在於\(A,B\)串中間的迴文串可以直接\(\text {manacher}\)求出,考慮“扭動”形成的迴文串。
枚舉迴文中心,因爲“扭動”的迴文串,必然在\(A\)\(B\)中對應有一個最長的迴文串,這是\(\text{manacher}\)就已經求出來了的,再用二分+哈希把兩串拼一起所形成的新串能夠再拓展的最大長度弄出來即可。

燈塔

其實就是要你對於每一個\(i\)求出\(p_i=\lceil\max\limits_{j}(a_j-a_i+\sqrt{|i-j|})\rceil\)

有一種做法就是對於每個\(i\)\(\sqrt{|i-j|}\)的取值不超過\(\sqrt n\)個,而且對於每個\(i\)和某個取值\(x\),所對應的\(j\)一定在一段或兩端連續的區間中,可以用st表查詢最大的\(a_j\),複雜度\(O(n\sqrt n)\)
另外一種做法只考慮\(j<i\)的情況,之後通過\(\text{reverse}\)求出\(j>i\)的情況,而可以發現決策點具有決策單調性,用決策單調性優化可以做到\(O(n\log n)\)

位運算

假設我們選出來的數\(A_1,A_2...A_N\)滿足,\(A_0> A_1\geq A_2...\geq A_N\),其中爲了方便我們令\(A_0=R\)
考慮狀壓這\(N+1\)個數的大小關係,那麼狀態\(s\)\(N\)位,每一位\(0/1\)表示\(A_i(>\text {or}\geq) A_{i+1}\),設\(f_{i,s}\)表示當前從高往低考慮到第\(i\)位大小關係爲\(s\)的方案數,枚舉當前位的填數情況\(t\)可以進行轉移,而對於每個循環的轉移時一樣的,處理完一個循環的情況後可以矩陣快速冪求出方案數。

炸彈攻擊

這題比較玄學,網上所查得到的大部分題解說是模擬退火實則爬山算法。
就直接按照隨機化的方法\(\text{rand}\)一個移動向量看是否更優即可,溫度、溫度變化量、eps以及一些退火中的tricks網上都有,這裏不再贅述。

飛機調度

首先可以想到\(\text{floyd}\)求出任意兩點之間的最短路,因爲存在維修時間所以要將\(dis_{i,j}\)設爲\(g_{i,j}+p_j\)
假設某一趟航班\(i\)\(x_i\rightarrow y_i\),時間由\(s_i\rightarrow t_i(t_i=s_i+T_{x_i,y_i}+p_{y_i})\),那麼對於航班\(j\),如果想讓\(i,j\)共用一趟飛機則必須滿足\(t_i+dis_{y_i,x_j}\leq s_j\)
我們將\(i\rightarrow j\)連一條邊,發現整張圖一定是個DAG,直接跑最小路徑覆蓋即可。

無界單詞

首先考慮第一問,設\(f_i\)表示長度爲\(i\)\(|border|=0\)的串的個數。
我們考慮容斥,減去\(|border|>0\)的情況,因爲如果\(|border|\geq \lceil\frac i2\rceil\),那麼可以減去中間公共部分變成\(<\lceil\frac i2\rceil\)的情況,所以有
\[ f_i=2^i-\sum_{j=1}^{\lfloor\frac i2\rfloor} f_j\times 2^{i-2j} \]
對於第二問考慮二分,則問題實際上變爲求前綴爲\(s\)時的\(f_i\)
顯然有\(f_i=[前i個字符無border],i\leq |s|\)
對於\(i>|s|\),則分類討論之:
首先有
\[ f_i=2^{i-|s|}-\sum_{j=1}^{\lfloor\frac i2\rfloor}f_j\times c_{i,j} \]
其中\(c_{i,j}\)表示係數,有:
\[ c_{i,j}= \begin{aligned} \begin{cases} 2^{i-2j}&j\geq |s|\\ 2^{i-|s|-j}&j+|s|\leq i\\ [s有長度爲j+|s|-i的border]& \text{otherwise} \end{cases} \end{aligned} \]
然後按照這種方法轉移就好了。

輕重路徑

首先可以用樹狀數組單點加、區間查詢維護每個點的\(size\)
考慮這一次我們刪掉了葉子\(x\),那麼對於\(x\)到根\(rt\)的路徑,如果要滿足上面的一個點\(u\)它要改變他由重變輕的話必有\(size_u\leq \frac {size_{rt}}2\),我們可以二分這個點,那麼這樣的話最多二分\(O(\log n)\)次。
判定一條邊是否從重邊變成輕邊的依據是父親的重兒子之前指向\(u\),同時刪除節點後有 \(size_u+1=size_{another\_son}\),注意特判\(u\)是父親子樹最後一個節點的情況。
複雜度\(O(n\log ^3n)\)但是樹狀數組以及樹剖、二分的常數都比較小,還有這題的思路感覺比較類似於CSP2019樹的重心。

病毒感染

題目的意思是如果往左走就要把之前左邊沒治癒的治癒完。
那麼整個過程可以分爲若干個子段,每個子段治完子段中的所有村莊然後再回到該子段的起點繼續治接下來的子段。
\(f_i\)表示目前在\(i\)\(1...i\)均治癒完畢的最小代價,轉移的話枚舉這個子段的起點:
\[ f_i=\min\limits_{j<i}\{f_j+[j\ne 0](s_n-s_j)+g_{j+1,i}+[i\ne n](i-j-1)(s_n-s_i)\} \]
其中\(s\)爲前綴和\(g_{i,j}\)\(i\)走到\(j\)再回到\(i\)所花費的最小代價。
考慮\(g_{i,j}\)\(g_{i+1,j}\)轉移過來,枚舉\(i\)在不在當時治癒有:
\[ g_{i,j}=g_{i+1,j}+\min\begin{cases}3a_i(j-i)+(s_n-s_i)+2(s_n-s_j)\\2(s_n-s_i)+(s_n-s_j)\end{cases} \]
然後就可以dp了。

反質數序列

考慮到奇數和奇數、偶數和偶數之間不可能爲質數,那麼所有元素就構成了一個二分圖。
其中奇、偶之間如果是質數的話就連一條邊,答案就是最大獨立集也就是\(|\mathbb V|-\)最大匹配,注意\(1\)選的個數不能超過\(1\),所以\(1\)只要保留一個。

炸彈攻擊2

考慮枚舉每一個發射源,算出每個發射源的貢獻。
將這個發射源作爲原點,將其他除了發射源之外的點放一起極角排序,因爲題目保證所有敵人都在己方單位上面,所以答案就是兩個極角不超過\(\pi\)的激光塔之間所夾的敵人數,又因爲這題實際上是個環的結構,所以需要斷環爲鏈+前綴和維護。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章