JZ模擬賽 8.9
B組:
T1:
農夫約的假期
Description:
在某國有一個叫農夫約的人,他養了很多羊,其中有兩頭名叫mm和hh,他們的歌聲十分好聽,被當地人稱為“魔音”······
農夫約也有自己的假期呀!他要去海邊度假,然而mm和hh不能離開他。沒辦法,他只好把他們兩個帶上。
到了海邊,農夫約把他的羊放在一個(n*n)的矩陣(有n*n個方格)裏。mm和hh十分好動,他們要走到m(m<=n*n)個地方,第i個地方的坐標為(x[i](行),y[i](列)),每到一個地方他們會高歌一曲,制造q[i]點魔音值,因為他們的魔音十分獨特,他們的聲音只能橫著或豎著傳播。每傳播一格,魔音值會增加1。(傳播的格子數取最小的)接下來農夫約要住酒店。為了方便照顧小羊們,他選的酒店的坐標要在矩陣內。但小羊們的魔音讓他十分頭疼。他想求出魔音值最小的地方。
他還要享受他的假期,所以他把這個任務交給你了,加油(^_^)。
概括:給定一些二維坐標點,求一個點,使得這些點到這個點的曼哈頓距離最小。
Output
第一行一個整數表示魔音值最小是多少。接下來一行兩個正整數zb1和zb2,表示魔音值最小的地方的坐標(如果有多個答案,輸出橫坐標最小的情況下,縱坐標最小的)。
Solution:
考慮縱坐標,一定是縱坐標中位數。
反證:如果不是,那麽比中位數大的點mid+1都會+1,mid個點-1,不論上下位移,都不優。
橫坐標同理。
由於橫坐標最小,縱坐標最小,所以如果偶數,選擇小的一個。
之後,乘一下z,然後加一下qi的和。這兩部分都是定值。
(話說JZOJ標程忘了乘z,結果無人AC~~)
T2:
小x遊世界樹
Description:
小x得到了一個(不可靠的)小道消息,傳說中的神島阿瓦隆在格陵蘭海的某處,據說那裏埋藏著亞瑟王的寶藏,這引起了小x的好奇,但當他想前往阿瓦隆時發現那裏只有聖誕節時才能到達,然而現在已經春天了,不甘心的他將自己的目的地改成了世界樹,他耗費了大量的時間,終於將自己傳送到了世界樹下。世界樹是一棵非常巨大的樹,它有著許許多多的枝條以及節點,每個節點上都有一個平臺。好不容易來到傳說中的世界樹下,小x當然要爬上去看看風景。小x每經過一條邊都會耗費體力值。然而世界樹之主想給他弄(gáo)些(dǐan)麻(shì)煩(qíng),於是他在每條邊上都設了一個魔法陣,當小x踏上那條邊時會被傳送回根節點,魔法陣只生效一次。這豈不是要累死小x?幸運的是,每個平臺上都有無數個加速器,這些加速器可以讓小x在當前節點所連的邊上耗費的體力值減少,不同平臺的加速器性能不一定相同,但同一個平臺的加速器性能絕對相同。世界樹之主給了小x一次“換根”的機會,他可以將世界樹的任何一個節點變為根,但所有的邊都不能改變。小x想問你,將根換為哪個節點能使小x爬到世界樹上的每個節點耗費的體力值和最少。默認編號為1的點為初始根。
(題目太麻煩)
給定一棵樹:你要選擇一個根,使得到每個點的距離之和最小。邊權根據題意,從兩個端點出發,可能加速器不一樣,權值不同。
Solution:
裸的二次掃描換根法。
首先dfs一遍,處理子樹大小,dis值之和。
再dfs一遍,從當前欽定根到一個兒子點的時候,這條邊影響了dis總和值。子樹外的點dis總和加上邊權,子樹點的dis總和減去邊權。註意,邊方向不同。
O(n)處理一下就好了。
T3:
觀察
Description:
出題人給出一顆以1為根的樹,一開始每個節點都是一顆棋子,一面白一面黑,白色的面朝上
接下來就q次操作,操作分兩種
0操作 將一個顆棋子翻轉
1操作 詢問一顆棋子與所有面朝上為黑色的棋子lca最深的那個(lca)的編號
Solution:
非常非常沒有思路是不是???
有一個不顯而易見的結論:
如果詢問求一個x,和它產生答案的黑點一定是dfs序中,x後繼黑點和x前驅黑點。
為什麽呢?
dfs有一個性質,一定會遍歷整個子樹之後,才會繼續搜索。
所以,
1.如果前驅\後繼在x子樹裏,顯然答案就是x,沒錯。
2.如果前驅是x的某個祖先y,說明,要麽x到y的路徑上其他子樹裏,不會有黑色節點,要麽有,就是後繼了。(否則不滿足dfs序先掃完一個子樹的性質了)
所以,要麽是前驅,要麽是後繼。
兩個分別lca,取深度較深的點即可。
怎麽求dfs序裏面,x前驅後繼呢?
1.set,按照dfs序排序,直接upper,lower
2.線段樹,區間以編號為下標(dfs序:1~n)維護這個區間內,黑點的個數。
每次找x,就是從[1~x-1]找最大的黑點,劃分logn區間後,優先找右子樹,有黑點就進,否則進左子樹。到了葉子就返回。
(我們也可以擴展一下,求k個點的lca,就是dfs序最小的一個,和dfs序最大的一個求lca)
修改直接改。
復雜度:m2logn
A組:
T1:
餐館
Description:
K妹的胡椒粉大賣,這辣味讓食客們感到刺激,許多餐館也買這位K妹的賬。有N家餐館,有N-1條道路,這N家餐館能相互到達。K妹從1號餐館開始。每一個單位時間,K妹可以在所在餐館賣完盡量多的胡椒粉,或者移動到有道路直接相連的隔壁餐館。第i家餐館最多需要A[i]瓶胡椒粉。K妹有M個單位的時間,問她最多能賣多少胡椒粉。
N,M<=500
Solution:
沒什麽可以說的。直接樹形背包。因為可能走一下子樹,再返回根。
所以:f[i][j][0/1]表示,從i出發往子樹裏面走,花j時間,不返回/返回的最優收益。
dp就好了。
T2:
Description:
Solution:
暴力分挺高的。20分暴力,50分P是質數,前綴積,再處理逆元一下就可以了。nlogn
P不是質數:
由於k是給定的。
不妨每k個作為一個塊。處理每個點到所在塊末尾的後綴積,和前綴積。
對於恰好在k裏,直接隨便輸出。
否則,兩個端點,l後綴積,r前綴積再乘一下就好了。
直接乘,避免了逆元。
T3:
隨機
Description:
Solution:
暴力n^2logn
發現,其實,設取min的操作答案是A,長度是m,區間為l,r
如果l不變,r更大,m變大,A可能變小。
但是要再取max,所以,當m>A的時候,再往後移r就沒有意義了。因為max只能更大。
之後,就後移l,m變小,A可能變大。
而A>m的時候,可以往後移,m雖然大了,但是A可能更小。
所以,每個點進一次,出一次,2n
註意時刻保證m>=2
但是,怎麽向區間加入點,刪除點的時候,快速更新A呢?
如果只是ai取min,直接一個multiset搞定。
但是這是一個差值。
所以,再開一個multiset2,記錄multiset1,就是存數的set,大小相鄰兩個數的差值。
顯然,set2裏面必然有一個是min{|si-sj|}
插入一個點ax,從set1找到後繼ay+1,前驅ay,把ay+1-ay的值從set2裏面刪掉一個。
把ax-ay,ay+1-ax放進set2,ax放進set1。
刪除一個點ax,找前驅後繼。
刪除ax-ay,ay+1-ax,放進ay+1-ay, set1刪除ax(倒著做一遍)
每次取set2.begin()就是min
JZ模擬賽 8.9