1. 程式人生 > >退役前的做題記錄2

退役前的做題記錄2

枚舉 spa trie 不能 數量 glog 最短路 註意 tco

[HNOI/AHOI2018]遊戲

一個想法就是預處理出每個點向左和向右拓展多少,\(O(1)\) 回答詢問。
暴力容易被卡。
正解比較牛逼,先把沒有門的縮成一個連通塊,對於相鄰兩個連通塊 \(i,i+1\) 來說,如果 \(i\)\(i+1\) 需要的鑰匙在 \(i+1\) 之後,那麽 \(i\) 不能到達 \(i+1\),此時肯定是先處理 \(i\) 更優;否則處理 \(i+1\) 更好。
那麽可以連成一個具有拓撲關系的 \(DAG\),按照拓撲序擴展即可。
因為每個連通塊只會擴展一次,所以復雜度線性。

[HNOI2018]排列

第一步轉化,令 \(q[p[i]]=i\),那麽題目變成:
有一些 \(q[a[i]]<q[i]\)

的限制,\(q\) 必須為排列,求 \(max(\sum_{i=1}^{n}w[i]q[i])\)
這個東西是可以建圖的,\(i\rightarrow a[i]\),不合法當且僅當有環
其它情況就是一棵樹(\(0\) 為根)
也就是在這個樹上依次選點,選 \(u\) 之前必須選擇其父親,第 \(i\) 次選的代價為 \(i\times w[u]\)
考慮貪心,對於一個當前權值最小的點 \(u\) 來說,如果父親是 \(0\),那麽肯定選它最優
否則,設父親為 \(fa\),那麽選完 \(fa\) 之後一定會選 \(u\),這樣就可以合並這兩個節點。
對於之後已經合並過的節點,設其權值和為 \(v[i]\)
,大小為 \(c[i]\)
那麽 \(i\) 先於 \(j\) 當且僅當
\(v[i]+c[i]\times v[j] \le v[j]+c[j]\times v[i]\)
也就是 \(i\) 的平均權值最小,以這個為關鍵字選最小的點就行了。
為了計算答案,把每個點的貢獻在合並的時候拆開計算即可。

[HNOI2018]毒瘤

容斥+ \(DP\)\(75pts\)
正解可以動態 \(DP\),或者維護 \(22\) 個關鍵點的虛樹,每一條鏈的轉移系數不變,預處理即可。

[JXOI2018]遊戲

不難發現,所有不能被其他數篩掉的數是一定要選的,只有選了這些數字才能結束
假設有 \(m\) 個,枚舉結束時間 \(x\)

,答案就是 \(\sum \binom{x-1}{m-1}m!(n-m)!x\)
埃氏篩法即可求出 \(m\)
(埃氏篩法復雜度 \(O(nloglogn)\) !!!)

[JXOI2018]排序問題

不難看出期望就是 \(\frac{(n+m)!}{\prod_{v=1}^{max}(cnt_v!)}\)\(cnt_v\) 表示 \(v\) 這個數出現的次數。
貪心就是直接把 \(m\) 個數字每次選擇一個 \(cnt\) 最小的加入,使得最後 \([l,r]\) 內每個數字出現的的次數盡量平均。
直接按照數字出現的次數排序,從大到小枚舉平均的次數是多少即可。

[JXOI2018]守衛

假設不能被n看到的是很多個區間 \([l_k,r_k]\)
不難發現一個性質:\([r_k+2,n]\) 的位置是看不到 \([l_k,r_k]\) 的位置的。所以 \(r_k,r_k+1\) 必選其一。
我們還註意到,對於 \(j<k,[l_k,r_k+1]\) 的位置是看不到 \([l_j,r_j]\) 的位置的,也就是說這些區間互相獨立。
然後就可以直接 \(DP\) 了。

[HAOI2018]奇怪的背包

不難發現一個性質:選出來的集合 \(S\) 要滿足 \(gcd(S,P)|w_i\) 才合法。
\(P\) 的約數取出來 \(v_i\)\(gcd\) 之後容斥即可
復雜度 \(O(d^2(P))\)\(d\)\(P\) 的約數個數。

[HAOI2018]蘋果樹

\(i\) 個點的樹的方案數 \(f_i\),到根的距離和為 \(g_i\),距離總合 \(h_i\)
顯然 \(f_i=i!\)
\(g_i\) 的合並要將左右的樹的 \(g\) 分別加上 \(1\)
\(h_i\) 的合並要將左右的樹的 \(g\) 分別加上 \(1\) 然後拼起來再加上左右的 \(h\)
最後 \(h_i\) 還要算上 \(g_i\)
更加優秀的做法
可以考慮每個子樹的貢獻,對於一棵 \(i\) 的子樹,大小為 \(x\),方案數為 \(\binom{n-i}{x-1}\times x!\),貢獻為 \(x\times(n-x)\)
對於子樹外面的情況,就是 \(i!(i-1)i(i+1)...(n-x-1)=(n-x-1)!i(i-1)\)
直接計算即可

[HAOI2018]反色遊戲

不難發現就是給你 \(n\) 個異或方程組,求解的個數。
下面假設都是有解的情況
對於一棵樹來說,顯然解最多一個,每次父親消去兒子的即可。
不難得到,如果有 \(x\) 條非樹邊,無論它們怎麽選擇,都一定有唯一的解,方案數就是 \(2^x\)
設有 \(n\) 個點,\(m\) 條邊,\(c\) 個連通塊,答案就是 \(2^{m-n+c}\)
只要討論每個連通塊是否有偶數個黑色即可判斷無解。
每次刪除一個點:分成割點,非割點討論即可。

[HAOI2018]字串覆蓋

思想比較簡單。
對於 \(r-l+1 > 50\) 的詢問,直接暴力貪心的每次選擇最靠前的位置匹配即可,SAM+線段樹+倍增可以很好的實現。
對於 \(r-l+1 \le 50\) 的詢問,離線下來,對於長度相同的倍增處理出上述的操作即可。
還是挺好寫的

[JSOI2018]列隊

不難發現一定是把區間 \([l,r]\) 排序之後一一匹配最優(交叉匹配肯定不優)。
同樣也不難發現一定存在一個分界點 \(x\) 使得小於等於 \(x\)\(a_i\) 的位置小於等於匹配的點,另外大於 \(x\) 的相反。
主席樹上二分就好了。

[JSOI2018]防禦網絡

顯然是要考慮每一條邊的貢獻,對於一條非樹邊(割邊),只要從它分開的兩個集合中各選大於 \(0\) 個點就好了。
主要的問題是環上的邊,不難發現,如果環上有 \(k\) 個點,那麽最長的那個間隔一定不會在斯坦納樹裏面。
可以枚舉環上第一個選的點為 \(st\),然後設 \(f_{i,j}\) 表示前 \(i\) 個,最大間隔為 \(j\) 的方案數(每個點個貢獻為 \(2^{x}-1\) 的形式),可以用前綴和優化輕易優化到 \(O(n^3)\)
n的4次方也挺快的

[JSOI2018]絕地反擊

第一想法是二分答案+二分圖匹配,合法的偏轉角只會是那些弧的端點,\(O(n^4logn)\)
又因為偏轉角不會超過 \(\frac{2\pi}{n}\),那麽可以在模 \(\frac{2\pi}{n}\) 意義下一路掃過去。每次最多加入(刪除)一條邊,退流即可。

[JSOI2018]機器人

神仙題,給結論跑路
\(d=gcd(n,m)\),那麽每一個 \(d\times d\) 的正方形矩陣同構,操作每 \(d\) 個一個循環。
設向右 \(x\) 步,向下 \(y=d-x\) 步,合法的方案當且僅當 \([x\perp d][x\perp n][y\perp m]\)
轉換:碰到障礙前走的路程 \(=\) 碰到每個障礙時走的路程的最小值。
處理出每個點 \((x,y)\) 在循環內走到的第一個障礙的距離,之後 \(DP\) 即可

[FJOI2018]所羅門王的寶藏

每個寶石的行和列連邊,表示兩者的操作的和為邊權
有解則同一個連通塊每個點一定可以用每個點的一次函數表示,\(dfs\) 即可

[FJOI2018]領導集團問題

一個顯然的 \(DP\)
\(f_{u,i} = [i=w_u] + \sum_{v \in son_u}max_{j \ge i} f_{v,j}\)
可以直接用線段樹合並維護,每次把右邊的最大值丟到左邊合並更新 \(max_{j \ge i} f_{v,j}\)
正確性:剛開始合並上來的 \(max_{j \ge i} f_{v,j}\) 一定是單調的。
最後只要單點修改即可。

[FJOI2018]郵遞員問題

亂搞。
可以發現如果起點在左邊界,終點在右邊界的時候上下走的點一定是連續的(可能吧)
那麽可以設 \(f_{i,j,0/1}\) 表示當前上面到 \(i\),下面到 \(j\),當前在上面/下面的最短距離。
如果起點不在左邊界,終點不在右邊界,那麽就亂搞。
對於左邊,如果向左的時候下去了再上來一定不會優與直接走過去,那麽就分兩種情況:左下右 或者 直接先左再次原路返回向右。
右邊類似,每次到一個點用這個策略更新一下答案。
之後交換左右再做一遍即可不想卡常了,BZOJ直接特判了QwQ
上述(假算法)策略成功水過了所有的測試點。

[TJOI2018]遊園會

經典 \(DP\)\(DP\)

[BJOI2018]求和

模擬即可。

[BJOI2018]二進制

一個顯然的結論,設串的長度為 \(n\),有 \(x\)\(1\)
那麽合法當且僅當:\(x\) 為偶數或者 \(x\) 為奇數 \(x>1\)\(n-x \le 2\)
也就是兩種情況:偶數個 \(1\) 或者奇數個 \(1\),大於 \(1\)\(1\),且大於 \(1\)\(0\)
設一個 \(f_{0/1,0/1/2,0/1/2}\) 全部記錄下來即可,線段樹上就維護前綴和後綴。
合並的時候直接 \(for^6\) (逃
本機穩定 \(0.95s\)然而BZOJ還是TLE了

[BJOI2018]治療之雨

\(c_i\) 表示 \(k\) 輪打中了 \(i\) 次的概率,\(c_i=\binom{k}{i}(\frac{1}{m+1})^{i}(\frac{m}{m+1})^{k-i}\)
\(f_i\) 表示當前 \(i\) 的生命值,到死去的期望。
\(f_0=0\)
\(f_i(1\le i < n)=\frac{1}{m+1}\sum_{j=0}^{i+1}f_{j}c_{i-j+1}+\frac{m}{m+1}\sum_{j=0}^{i}f_{j}c_{i-j}+1\)
\(f_n=\sum_{i=0}^{n}c_if_{n-i}+1\)
\(x=f_1\),把所有的 \(f_i\) 表示成 \(a_ix+b_i\) 的形式求解即可。
我怎麽又在BZOJ上TLE了???

[BJOI2018]鏈上二次求和

線段樹維護二維前綴和即可,討論一下標記的系數。
最近隨便寫個題在BZOJ都TLE了QwQ

[BJOI2018]染色

大前提:肯定是二分圖才有可能合法。
一條長度為奇數的鏈是可以直接 \((A,B)\) 縮成一個點。
然後是各種情況:
(a)對於同一個連通塊,存在兩個環之間最多只有一條公共點,可以通過一個環強制一個點的顏色卡掉。所以環都要交織在一起。。
(b)對於兩個環,如果它們的交是奇數(大於 \(1\)),並且各自不交的部分大於 \(1\),也可以卡掉:
可以通過左邊的環構造出交的兩端至少有一個為固定的顏色,經過另一個環可以使得交的另一個端點的顏色不同,這樣就卡掉了。
(c)對於兩個環,如果它們的交是偶數(大於 \(1\)),並且各自不交的部分大於 \(1\),也可以卡掉:
使得交的兩個端點都是 \((A,B)\),那麽可以把交的都變成 \((A,B)\),這樣端點必定不同,只有兩種情況,分別在左右的環中卡掉。
(d)剩下的情況:一個連通塊就是一個簡單環或者樹;兩個環的非交部分都是 \(1\);可以發現這樣的東西怎麽玩都卡不掉。
這個題目怎麽這樣啊
綜上所述,最後合法的圖的情況:
(a)一個連通塊中 \(n\ge m\)
(b)一個連通塊中 \(n+1=m\),且是兩個環的非交部分都是 \(1\) 的情況。

[BJOI2018]雙人猜數遊戲

好神啊,反正這個遊戲我是不會玩。。。
考慮 \(Alice\) 一次不知道會告訴 \(Bob\) 什麽,顯然 \(Bob\) 可以窮舉自己的每一種可能的方案,看看是否有可能使得 \(Alice\) 的方案唯一。
\(Bob\) 不知道同理。
所以可以直接設 \(f[i][j][k]\) 表示第 \(i\) 輪,兩個人是否都不知道 \(j,k\) 這組數字,記憶化搜索即可。

[ZJOI2018]胖

處理出每個與 \(0\) 相鄰的點能更新的區間 \(L_i, R_i\)\(ans=\sum (R_i-L_i+1)\)
可以通過二分 + 線段樹實現,邊界情況比較難以判斷,註意一下。

[九省聯考2018]一雙木棋chess

爆搜,狀態不多,直接 \(hash\) + 記憶化

Codeforces 891C:Envy

因為最小生成樹的性質,分開考慮相同邊權的邊能否加入,只要預處理出加入小於某個邊權的邊之後的圖的連通性即可判斷。
一個不用可持久化並查集的方法就是:記錄下每一條邊在邊權小於它的所有邊之後的端點的連通塊編號。

Atcoder2134:Zigzag MST

因為 \((a,b,c)\) 邊權大於 \((a+1,b,c+1)\),那麽 \((a,b)\) 肯定會在 \((a+1,b,c+1)\) 之前就連通。
那麽在不改變連通性的情況下顯然可以把 \((a+1,b,c+1)\) 變成 \((a,a+1,c+1)\)
這樣加邊就變成了 \((a,b,c),(a,a+1,c+1),(b,b+1,c+2)...\)
\((a,b,c)\) 單獨拿出來,加上相鄰兩個點的最短邊做 \(kruskal\) 即可。

Atcoder3611:Tree MST

點分治,每次考慮把所有的子樹連通,顯然是離分治中心最近的點向所有的點連邊,這樣肯定比其它連法更優。

[Snoi2017]炸彈

左邊和右邊第一個能爆炸這個點的點向這個點連邊,單調棧可以實現。
\(tarjan\) 縮點之後,變成求 \(DAG\) 能到達的點的個數。
由於題目性質,到達的點一定是一個連續的區間,記錄左右端點即可。
復雜度 \(O(n)\)

[JSOI2012]越獄老虎橋

拿出所有的割邊排序,找到一個恰好不能用一條鏈覆蓋的前綴,輸出這個前綴的最後的邊權即可。
然後我就寫了個二分。。

牛客Wannafly挑戰賽9 E:組一組

分開考慮每一位,前綴和之後差分約束。
註意相鄰兩個前綴和 \(S_i,S_{i+1}\) 要滿足 \(S_i \le S_{i+1}\),且 \(S_{i+1}\le S_i+1\),因為最多有一個二進制位的貢獻。
剪枝

BZOJ4886: [Lydsy1705月賽]疊塔遊戲

顯然每種寬度只選擇一個就可以了,對於一個卡牌,連邊 \((a_i,b_i)\)
最後就是要給邊定向,答案為每個點的出度乘以權值。
因為題目保證有解,那麽一個連通塊要麽是樹,要麽是基環樹。
對於樹,選擇權值最大的點作為根即可。
對於基環樹,怎麽選每個點都要有 \(1\) 的入度,所以不用管。
以上均可以用並查集實現。

Codechef:Querying on a Grid

分治,類似於“[ZJOI2016]旅行者”維護每個分治中心三個點的最短路徑樹。
查詢距離就是找到每一個包含這個區間的分治中心,取距離 \(min\)
修改就是找到其中一個滿足距離等於最短路的分治中心,單點修改,子樹查詢。
查詢點就是找到所有包含這個點的分治中心,求和。

牛客Wannafly挑戰賽4 F:線路規劃

最小生成樹。
樹上用 \(ST\) 表優化連邊,註意不能首先連接到 \(ST\) 表上之後 \(pushdown\),因為不能確定下面的點的連通情況。
做法是每次暴力遞歸 \(ST\) 表連邊,碰到連好了的就返回。
因為 \(ST\) 表一共 \(log\) 層,每一層只會合並 \(O(n)\) 次,所以復雜度正確。

LOJ6036:「雅禮集訓 2017 Day4」編碼

\(trie\) 加鏈上前後綴連邊,連完之後求 \(2-sat\) 即可。

UOJ236:[IOI2016]railroad

題目可以轉化成這樣:
給定一些有向邊 \((s_i,t_i)\),你需要加入一些邊使得存在歐拉路徑,並且圖連通。
邊權:向左連邊代價為距離,向右連邊無代價。
求最小代價。
首先可以加入邊 \((inf,1)\),這樣就變成了歐拉回路問題。
我們考慮數軸上的一個間距,如果存在歐拉回路,那麽在這個間距上向左和向右的邊的數量必須相等。
那麽可以先求出每個間距的貢獻。
但是這樣只能使一段還需要加邊的區間連通。
所以再把相鄰兩個不連通的區間之間的邊拿出來跑一遍最小生成樹即可。

退役前的做題記錄2