1. 程式人生 > >HNOI2015題解

HNOI2015題解

pop abs read ria pan 在線算法 position 數據結構 最優

奇了怪了我上次發的題解怎麽不見了?
題意自己戳鏈接……

Day 1

id=4008">HNOI2015 Arthur

思路:期望DP
直接DP是死也D不出的
轉化一下
令f[i][j]——第i張卡在第j回合發動的概率
得到狀態轉移方程:
f[i][j]f[i?1][j]?(1?pi?1)j+f[i?1][j+1]?(1?(1?pi?1)j+1)
這樣下來,答案就為:
ni=1rj=1f[i][j]?(1?(1?pi)j

)?di
時間復雜度:O(Tnr)

id=4009">HNOI2015 Fruit

思路:DFS序+總體二分+線段樹
設pos[x]——x在DFS序中的位置
我們將水果轉化為二維平面上的點(x,y),則有:
每一個盤子能夠接到的水果為二維平面上的若幹矩形:
對於盤子(x,y),最好還是設deep[x]< deep[y]
若x為y的祖先,則該盤子能夠接到的水果滿足:一個端點在y的子樹內。還有一個端點在x的子樹外
否則能夠接到的水果滿足:一個端點在x的子樹內,還有一個端點在y的子樹內

假設在這裏套上樹分治,能夠將矩形規模縮小到P*logN
(Orz考場上N*log

3N水過的matthew99爺)
只是我們直接使用DFS序(pos[x],pos[y])。能夠將矩形規模縮小到2
於是問題變成,二維平面上若幹矩形和若幹詢問點,對於每一個詢問點求覆蓋它的矩形的第k大。可離線
在線算法挺麻煩的……
總體二分就可以解決這個問題
對於區間[l,r]內的矩形。我們考慮[l,mid]對每一個詢問點的覆蓋次數
若覆蓋次數超過相應的詢問k,則說明答案在[mid+1,r]中
否則說明答案在[l,r]中
將詢問點分成兩份後。遞歸處理就可以
時間復雜度:O(Nlog2N)

HNOI2015 Dishes

思路:優先隊列+字典序
首先排除無解情況
若給定優先順序出現環狀,則說明無解
否則我們考慮整個序列
在1最優先的情況下,使2最優先
將整個序列倒過來,則有:
在1最後的情況下,使2盡量靠後
顯然:字典序最大

將整個圖倒過來建
每次取可行的最大解增加答案
最後將答案倒序輸出就可以
時間復雜度:O(NlogN)

Day 2

HNOI2015 Maple

思路:DAG上DP
di為i點的入度
對於一個DAG,我們會發現答案為ans=Πni=2di
麻煩的就是多了一條邊
這時我們會發現答案增大了
這些增大的方案為那個新邊構成的環數
設新邊為(x,y),我們能夠DP求得增大的方案數
f[i]——y->i對答案的增大的數目
顯然:f[i]=j?>if[j]?d?1i
初始狀態:f[y]=ans?d?1y
答案:ans?f[x]
在模質數下可將除法轉化為乘法逆元
時間復雜度:O(N+M)

id=4012">HNOI2015 Shop

思路:可持久化樹分治結構
事實上沒有思路上說的那麽復雜……
假設是離線的話,直接一個樹分治就搞定
然而題目強制在線。只是每一個點度數不超過3

假設Q=1,我們僅僅需一次樹分治
若Q=100。我們能夠進行100次樹分治
然而Q=200000……
不慫。我們考慮每次樹分治
我們會發現,每次分治選出的重心都是一樣的
我們將這些重心拎出來,又一次構成一棵樹
我們稱之為分支結構樹
顯然,這棵樹的深度不超過logN
對於每一個詢問,我們發現。僅僅有在分治結構樹這個點和它的祖先的答案對這個詢問有答案貢獻
假設度數>3,我們就須要一個可持久化數據結構來維護每一個重心在分支結構樹中的答案
只是這個題度數小,我們能夠開3個vector,然後直接合並答案
這樣我們僅僅需在分治結構樹中計算這個點和它的祖先的答案就可以
時間復雜度:O(QlogN)

id=4013">HNOI2015 Pairwise

思路:樹形DP
首先將相等的縮成一個點
然後考慮無解狀況,相似Day1 T3
設:一個序列的長度為’<’個數+1
對整個森林進行DP
f[i][j]——以i為根的子樹產生的長度為j的序列個數
狀態轉移方程:f[i][j]=合並f[son[i]][k]
這個合並能夠利用背包解決
問題轉化為,對於一個長度為x的序列和一個長度為y的序列,將其轉化為長度為z的序列共同擁有多少種方案
依據基本組合知識能夠知道:(xz)×(x+y?z x)
時間復雜度:O(N^4)

HNOI2015題解