PKUSC2021 簡要題解


如果有同學需要我的代碼的話可以私我要,題面也可以私

當然由於本人很菜,代碼和做法不一定是對的,但是一定是過了自己造的對拍


D1T1 Sum Transformation

假設原矩陣第\(i\)行的和是\(a_i\),第\(j\)列的和是\(b_j\),整個矩陣的和是\(S\)

那么變換一次以后\((i,j)\)的位置就會變成\(a_i+b_j\)

考慮變換的第二次,簡單推導一下,\((i,j)\)位置就會變成\(n(a_i+b_j)+2S\)

不難發現,\((i,j)\)位置的值一定可以用\(p(a_i+b_j)+q\)來表示,這個系數對於每一個位置是相同的

這個系數顯然可以矩陣乘法遞推解決

時間復雜度\(O(logT+n^2)\)



D1T2 逛街

如果沒有修改,我們發現把每個\(i\)向最小的\(j>i\)滿足\(a_j>a_i\)連邊(找不到就往\(n+1\)連),這樣會得到一棵樹

在樹上倍增就可以回答詢問

注意到所有的相同的數一定是連成一段的

有修改就意味着一些數可能被覆蓋掉,消失了

也就是樹上的一些點被刪掉了


先考慮sub2,所有修改是對於全局的

不難發現這樣我們的刪除只會刪除葉子

考慮反證法,如果我們修改中刪去了一個非葉子節點,那么由於是全局修改,它一定會往它的兒子擴展一步,它就出現在了新的位置,矛盾

於是詢問\([l,r]\)我們就只需要在\(l\)處找到樹中祖先上第一個還存在的節點,再倍增跳上去,直到跳出當前\(r\)處的范圍即可

找葉子可以用st表求區間最大值的位置


考慮sub3,所有修改是任意的

不難發現這樣就可能會刪除非葉子節點

但是可以看到的是,樹的結構並不會改變,因為一個點它的父親被刪除了,它在樹上的新父親一定是它父親的父親,姑且稱之為爺爺

證明考慮反證,假設它的父親是\(x\),爺爺是\(y\),能找到的新父親是\(z\),那么有\(a_y>a_x>a_z\)\(x<z<y\),不難發現此時如果\(x\)\(y\)覆蓋掉了,由於\(z\)\(x,y\)中間,所以\(z\)也一定被覆蓋了,矛盾

所以這棵樹是可以一直使用的

我們刪除非葉子節點時並不在樹上顯式地刪除它,而是采取一個懶惰刪除的方式,只是把他的權值置為\(0\),查詢時查詢鏈和即可

接下來我們還可以證明,盡管可能會刪去非葉子節點,但是刪去的非葉子節點一定出現在修改區間左端點處

因為只有左端點處的數才不能繼續往左擴展,修改區間內部只會刪去葉子,這一點的證明跟前面sub2里的證明是類似的


於是一個做法就呼之欲出了

只要我們能夠維護每個位置當前的數並支持單點查詢,就能夠在樹上刪去非葉子節點的權值,並找到第一個非葉子節點並在樹上完成倍增,查詢鏈權值可以用樹狀數組\(O(logn)\)維護

考慮維護每個位置會對右側的哪些點取max,不難發現這是一個連續區間,設右端點是\(r_i\),我們只需維護\(r_i\)

於是修改\([L,R)\)其實是讓\(\forall i \in [L,R) , r_{i}=r_{i+1}\)

不難發現就是刪去\(L\)這個位置的數,並在\(R\)這個位置補充一個原來的\(r_R\)

顯然平衡樹就是合適的數據結構

總時間復雜度\(O((n+q)logn)\)

代碼4.2k,還是挺好寫的



D1T3 德州撲克

不會真的有“人”會做吧?



D2T1 一棵樹

不刪邊sb題隨便搞

考慮我們刪除某條邊造成的總貢獻

考慮刪邊后形成的兩側子樹A,B中每條邊的貢獻

對於A中的每條邊,他的貢獻就是以A中每個點作根,這條邊遠根處的size之和,再乘上B的size

不難發現我們只需換根dp出以一個點為根,所有點的size和

就可以方便計算出兩側的貢獻了

時間復雜度\(O(n)\)

實現細節不少



D2T2 代金券

不難發現一個貪心策略,就是優惠券盡量留在最后來用

發現這樣不完全對,優惠券在前面也是可能會使用一部分的,只要不影響獲得獲得優惠券的數量,也就是\(a_i \ mod\ c\)以內的可以隨便用

於是進一步,我們可以歸納出完整的策略

存在且只存在一個\(i\),滿足

對於\([1,i-1]\)中的菜品\(j\),我們最多用\(a_j \ mod \ c\)張優惠券,並且盡量多用

對於\([i+1,n]\)中的菜品\(j\),我們能夠全部用優惠券支付

對於\(i\)處的菜品,我們用一些優惠券,再用一部分現金來獲得優惠券,使得最后恰好優惠券能用完

同時不難發現這個\(i\)滿足

\([i,n]\)中的菜品全部使用代金券支付的時候代金券不夠用

\([i+1,n]\)中的菜品全部使用代金券支付的時候代金券夠用

於是我們只需要找到這個\(i\)即可

因為有修改,暴力維護和查找是\(O(nq)\)

考慮用線段樹來維護這個東西

考慮前半部分你對於一個菜品\(j\),假設你當前有\(x\)張優惠券

那么你買它之后的優惠券是 \(x=max(x-a_j\ mod\ c,0)\)\(x+=\lfloor \frac{a_j}{c} \rfloor\) 也就是 \(x=max(x+(\lfloor \frac{a_j}{c} \rfloor - a_j\ mod\ c),\lfloor \frac{a_j}{c} \rfloor)\)

注意\(x=max(x+a,b)\)這樣的標記滿足結合律,但是沒有交換律

\((a,b)\)\((c,d)\)合並以后就是\((a+c,max(b+c,d))\)

於是你可以很方便地維護購買一個前綴以后的優惠券數量

所以我們在線段樹上二分就能找到分界點\(i\)

前半部分使用的現金可以用總花費減去用掉的優惠券算出

\(i\)處使用的現金只需二分即可

總時間復雜度\(O((n+q)logn)\)



D2T3 招新

神仙題我寫了三個做法來拍

考慮整數部分和小數部分是可以拆開來計算的

我們可以枚舉小數部分的大小關系,來計算整數部分的分配方案

最后除以所有滿足\(0<x_1<x_2....<x_n<m\)的方案即可,這部分顯然是\(m^n\)

具體組合意義的證明可以考慮給小數部分大小排名為\(i\)的確定一個整數部分,這樣分配的方案,排序以后,與上面的方案一一對應


做法1:裸暴力

直接\(O(n!)\)枚舉小數部分的大小關系,然后接下來的dp是trivial的

\(f[i][j][k]\)表示討論了前\(i\)個數,第\(i-1\)個數整數部分是\(j\),第\(i\)個數整數部分是\(k\)的方案數

轉移前綴和優化下,總復雜度\(O(n!nm^2)\)


做法2:暴力dp

注意到我們的轉移只需考慮\(i\)小數部分與\(i-1\)\(i-2\)小數部分的大小關系,並不關心他們在最終的序列中排名究竟是第幾

於是我們只需要記在前\(i\)個數小數部分排名中,他們的相對排名即可

\(f[i][a][x][b][y]\)表示討論了前\(i\)個數,第\(i\)個數小數部分排名是\(a\),整數部分是\(x\),第\(i-1\)個數小數部分排名是\(b\),整數部分是\(y\)的方案

\(b<a\)\(y<x\),從\(f[i-1][b][y][c][z]\)轉移過來時需要滿足\(c<a \ and \ z \leq x-K\)\(c \geq a \ and \ z \leq x-K-1\),不難發現這是兩個矩形,在固定\(b\)\(y\)的時候可以二維前綴和優化

\(b>a\)時同理

總復雜度\(O(n^3m^2)\),極限數據約10s,造數據是夠用了


做法3:優化dp

注意到上面的dp轉移時當\(x-y \geq K+1\)時,任意\(z \leq y\)均滿足條件,而\(z \leq y\)是顯然的

於是這啟示我們只需記錄\(x-y\)的值即可,並且可以把\(x-y \geq K+1\)的合並

修改dp狀態

\(f[i][a][x][b][y]\)表示討論了前\(i\)個數,第\(i\)個數小數部分排名是\(a\),整數部分是\(x\),第\(i-1\)個數小數部分排名是\(b\),整數部分與第\(i\)個數的差是\(y\)的方案,其中\(y \leq K+1\)

\(0 \leq y \leq K\)轉移同上略微討論

\(y=K+1\)時是一個整體和,也可以前綴和處理

總復雜度\(O(n^3km)\),看起來沒啥優化

但是請注意當\(\lfloor \frac{n-1}{2} \rfloor k \geq m\)時答案是\(0\),可以直接判掉

所以\(nk\)其實是\(O(m)\)級別的

時間復雜度降為\(O(n^2m^2)\),可以在2s內跑出極限數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM