如果有同學需要我的代碼的話可以私我要,題面也可以私
當然由於本人很菜,代碼和做法不一定是對的,但是一定是過了自己造的對拍
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內跑出極限數據
