由於太懶了,沒什么意思的題就寫一句話題解了
10.07
分別對\(\sum a,\sum b\)開狀態開不下,考慮到\(a_i\leq b_i\),所以任意時刻都有\(\sum a\leq \sum b\),所以設\(dp_{i,j}\)表示選到了第\(i\)個數滿足\(\sum a\leq j\leq \sum b\)的最小代價,顯然有轉移\(dp_{i,j}=\min_{k=j-b_i}^{j-a_i}dp_{i-1,k}+c_i\),單調隊列優化轉移即可
兩個數異或起來只有兩個\(1\),考慮枚舉這兩個\(1\)分別在哪里,即對於\(c=2^i+2^j(i\neq j)\),求有多少對\(a_i\bigoplus b_j=c\),拆一下式子變成了\((a_i\bigoplus 2^i)\bigoplus (b_j\bigoplus 2^j)=0,i\neq j\),於是我們能將每一個\(a,b\)搞成\(\log\)個數,得到了兩個\(n\log n\)長的數列,求一下這兩個數列有多少對相等的數對即可。考慮\(i\neq j\)的限制,發現對於原數列一對相等的數,在每一個數位都會被計算一次,於是還要減掉原數列里相等的數對個數乘上數位個數。
通過玄妙的掛鏈hash能做到\(O(n\log n)\)。寫兩個\(\log\)基本都被卡了,比如說不會hash的我。
分析一下不難發現對於所有“添”連邊得到的圖一定是仙人掌(因為保證三線不共點,所以一條邊不會出現在兩個簡單環里)
眾所周知,給仙人掌染色最多只需要三種顏色。當且僅當存在奇環的時候,需要用到的顏色數是\(3\)。我們發現當且僅當有不少於三種斜率的時候一定會存在奇環(三種斜率一定會構成一個三角形,而三角形是一個三元環),於是判斷一下是否存在三種或以上不同斜率即可;
不難發現只需要按\(\frac{t_i}{p_i}\)從小到大排序之后順着選過去;修改用線段樹維護一下即可。
用一個樹上差分能夠維護出每一條邊被經過的次數,如果選定了根我們貪心的選擇經過次數最大的那條邊作為重兒子即可。所以隨便先定一個根,大力換根即可。由於換根的時候可能會把原來的重兒子換成根,所以對於每個點要維護最大兒子和次大兒子。
\(x,y\)滿足\(x\)異或\(y\)在二進制下有奇數個\(1\)當且僅當\(cnt(x)\bigoplus cnt(y)=1\),\(cnt(x)\)表示\(x\)二進制下\(1\)的個數。這個結論非常簡單,因為\(cnt(x\bigoplus y)=cnt(x)+cnt(y)-2\times cnt(x\&y)\),又因為運算在模\(2\)意義下所以后面那個\(2\times cnt(x\&y)\)相當於沒有。於是維護當前區間並內有奇數、偶數個\(1\)的數分別有多少個即可。
我們把所有區間視為左閉右開的形式,把所有區間的端點拿下來排序建線段樹。相鄰兩個端點之間用數位dp算有奇數個\(1\)的數的個數,用線段樹維護區間並即可。
對於所有\(1\)到\(n\)的排列\(p\),使\(i\)向\(p_i\)連邊,問期望環的個數
答案即\(\frac{\sum_{i=1}^n\begin{bmatrix}n\\i\end{bmatrix}i}{n!}\),設\(f_n=\sum_{i=1}^n\begin{bmatrix}n\\i\end{bmatrix}i\),則有
不過好像有更簡單的方法說明答案就是\(\sum_{i=1}^n\frac{1}{i}\)
求一下差分數組,記差分數組中所有小於\(-k\)的與\(-k\)的差為\(A\),大於\(k\)的與\(k\)的差為\(B\),答案就是\(\max(A,B)\)
證明比較簡單,設\(A<B\),我們使用\(A\)的代價把所有小於\(-k\)的都調整到\(-k\),使得差分數組只剩下大於\(k\)的,在用\(B-A\)的代價把這些調整到\(K\)即可;由於差分數組的和為\(0\),這樣的調整方案是一定存在的。
10.08
顯然當長度為\(2^i\)的時候最優策略就是一直折半,答案就是\(2^i-1\);
對於更一般的情況,感性理解一下分成一些\(2\)的次冪一定是最優的
首先先把必須連的邊都連上,如果出環就是\(-1\);再暴力一下兩個點\(i,j\),看看\(i,j\)是否能連邊,用這些邊和必須連的邊跑一棵生成樹,輸出這些邊即可。
樹是一個\(n\)個點\(n-1\)條邊的無向連通圖,也就是說刪除一個點后必須剩下\(n-2\)條邊,且圖聯通就能保證是一棵樹
所以我們刪的點必須是度數為\(m-(n-1-1)=m-n+2\)的非割點,tarjan求一下即可。
發現如果滿足\(n\%(k-1)=1\)的話就是一個\(k\)叉的哈夫曼樹,開一個小根堆,暴力拿出重量前\(k\)小的合並成一堆即可。又要求最大深度最小,所以額外記一個最大深度作為第二關鍵字。
當\(n\%(k-1)\neq 1\)時,我們需要確定一個第一次的合並量\(i\),使得\((n-i+1)\%(k-1)=1\),顯然這個第一次合並量越小越好,我們枚舉這個\(i\),先把這\(i\)個合並起來;之后再按照\(n\%(k-1)=1\)的方式合並
我們發現答案就是最大的修改量,於是二分一下這個最大修改量,這樣每個數能形成的取值就是一個區間。問題變成了能否給每個數一個取值使得序列單調不降,直接貪心即可。
傻題,討論一下最大值,無腦分治即可
貪心,感性理解一下我們應該放回去的是下一次出現最晚的那一個,於是用大根堆維護一下。一個坑點是堆中的元素的下一次出現時間必須動態更新,並不需要可刪堆,由於新插入的下一次出現時間一定更大,所以直接插入即可。
只會一個無腦做法。我們發現在序列里多次添加同一個數並不會使得前綴\(\gcd\)的變化次數增加,所以這題和UR1的外星人非常相似。
先對於每一個數求一下把這個數放在第一個前綴\(\gcd\)的最大變化次數。之后設\(dp_i\)表示當前前綴\(\gcd\)為\(i\)的序列有多少種,我們發現從\(i\)向\(i\)的約數\(j\)轉移的時候,會有\(\left \lfloor \frac{n}{j} \right \rfloor-\left \lfloor \frac{n}{i} \right \rfloor\)個數變得沒有作用,所以我們乘上一個排列數讓這些數排列進去
更詳細的題解還是看看神仙寫的吧。更高論的做法好像需要在dp過程中存下\(2\)和\(3\)的次冪,過於高論就不會了。
10.09
答案就是行動次數最多的機器人的行動次數,二分這個行動次數\(mid\)
先所有物品按照重量排序,把這些物品依次加入一個以體積為序的大根堆里,每個有重量限制的機器人貪心地選擇質量小於其限制的體積前\(mid\)大的物品;剩下的物品就只有了體積限制,讓有體積限制的機器人貪心選就可以了。
難點在於讀題,就是瞎推幾下把目標環推出來,之后把初始的環摁在上面匹配就好了。初始環要從兩個方向都匹配一遍,否則會WA80
把所有操作倒過來,這樣就不用考慮當前操作對一個已經染過染色的格子的影響了,只要使得一個格子僅被訪問常數次就能做到\(O(n+m)\)的復雜度,所以使用並查集維護已經染好顏色的格子即可
鏈接里就是題解
10.10
鏈接里就是題解
發現這個\(x+1,x+2...x+c-1\)都出現但\(x\)和\(x+c\)不出現不是很好限制,考慮容斥一下,求連續\(c-1\)個出現-\(2\times\)連續\(c\)個出現+連續\(c+1\)個出現即可。
考慮離線,把所有詢問按照右端點排序,維護當前每種值最靠右的位置,同時維護值域上所有長度為\(1\)到\(c+1\)的區間的最小值。每更新一個數,可能影響到的區間就有\(c^2\)個,我們直接暴力這些區間,並去樹狀數組上修改這個區間對應的最小值。查詢的時候直接查詢有多少個長度為\(c\)的區間最小值不小於\(l\)即可。據慎老師分析,復雜度只有\(O(nc^2+(n+m)\log n)\)
貓哥的走位有點迷,於是先搞個預處理\(id[i][j]\)表示貓在\(i\),鼠在\(j\)的時候下一步貓的走位;不難發現因為期望的線性性,我們可以直接搞一個\(dp_{i,j}\)表示貓在\(i\),鼠在\(j\)的時候期望走幾步,直接記搜轉移即可
把題意轉化一下大概就是求\(f_i=\sum_{j}[dep_j\leq dep_i]dep_{LCA(i,j)}\),考慮先求出所有點和\(i\)的\(LCA\)的深度和,再減掉深度比\(i\)大的。顯然深度大於點\(i\)的點一定在深度和\(i\)相等的點的子樹中,於是我們直接對深度相同的點建虛樹,把虛樹上每個葉子的點權設為子樹大小減1,問題轉化成了對於每一個葉子求其他葉子和它形成的\(LCA\)的深度乘葉子的點權,在虛樹上瞎搞一波就行了
10.11
發現這個最低扣成\(0\)導致不是無法直接算貢獻,於是\(2^k\)枚舉一下哪幾個部分大零蛋,其余部分照常算,扣成負數也不要緊;顯然這樣不會使得最優答案變小或一個較小的答案變大。里面套一個\(dp_{i,j,k}\)表示用完第\(i\)個句子,填了\(j\)行,第\(j\)行填了\(k\)個字的最小扣分。大力轉移就好了。
顯然這個次大公約數就是\(\gcd\)除以最小質因子,注意到和\(a_1\)取\(\gcd\)之后一定是\(a_1\)的約數,所以我們將\(a_1\)質因數分解,搜出其所有約數,搜的時候就能方便的得到所有約數的最小質因子了
吉老師的小清新\(dp\),搞了好久搞出一個不一樣的做法,題解在鏈接里
晚上打了場牛客,成功讓我知道vector<int> d[maxn]
有多慢,由於卡B卡不過去搞了很久,之后還一邊寫題一邊和瞎頹,導致沒有時間去rush一個E,成功4題滾粗+罰時爆炸
10.12
顯然是個垃圾題,維護一下每一個質因子最后一次出現的位置,大力離線+樹狀數組即可
顯然是個簡單題,大力狀壓每個點到根的路徑上的狀態,設\(dp_{i,s,j}\)表示\(i\)點到根的路徑上的狀態為\(s\),子樹內部有\(j\)個農民參戰了,貢獻直接在葉子節點算好,往上只需要把左右兒子合並一下即可。注意到后兩維的狀態的乘積始終是\(2^n\),合並成一維就好了,所以空間復雜度是\(O(2^{2n})\),再分析一波發現每一層節點對時間復雜度的貢獻相同,所以時間復雜度是\(O(n2^{2n})\),所以難點在於對時間復雜度的分析。
比較玄幻的貪心,注意到我們要最小化的東西是\(\sum b_it_i-\sum A_i\),\(b_i\)是在站點\(i\)下車的人數,\(t_i\)是到達站點\(i\)的時間,\(\sum A_i\)是個定值不用管他。於是最小化\(\sum b_it_i\)即可。
考慮到我們在某一段道路上用一個加速器會使得后面所有的\(t_i\)都減小\(1\),所以看起來我們好像是應該在盡量靠前的地方使用加速器。但是注意到有一些車等人的情況,我們發現我們對於一條道路用了加速器,結果后面的某處車停下來等人了,於是並沒有使得車等人站點更靠后的站點的到達時間減小。
於是我們分一下段,使得同一段內都是人在等車,每一條道路的價值是同一段里位置更靠后的站點的\(b_i\)的和,貪心地選出價值最大的一條道路使得這條道路的\(d_i\)減一即可。之后繼續分段,做\(k\)次之后就是答案了,復雜度是\(O(nk)\)的,loj上有數據加強版看起來非常牛逼的樣子。
10.13
如果我們求出來一個叫做\(f(i)\)的東西表示序列的\(\gcd=i\)時\(\rm lcm\)的乘積,那么答案就是\(\prod_{i=1}^mf(i)^i\)
大力反演一波
\(F(i)\)表示序列的每個數的取值都是\([1,i]\)時所有\(\rm lcm\)的乘積,\(g(i)=i^n\),每個數的取值都是\([1,\left \lfloor \frac{m}{d} \right \rfloor]\)的時候再乘上一個\(d\)序列的\(\gcd\)就是\(d\)或\(d\)的倍數,這一共有\(\left \lfloor \frac{m}{d} \right \rfloor^n\)個序列,也一共有\(\left \lfloor \frac{m}{d} \right \rfloor^n\)個\(\rm lcm\),每個\(\rm lcm\)都乘上\(d\)就是真實的\(\rm lcm\)
於是問題就變成了怎么求\(F(i)\),顯然很好求我們算一下每個指數次冪的貢獻就可以了,復雜度是\(O(m\log^2m)\)
10.14-10.16
打了三天zr的模擬賽,天天被錘爆
10.17
注意到是個\(\rm DAG\),於是就先check一下每一條邊是否在\(1\)到\(n\)的路徑上;如果滿足\(1\)到\(n\)所有路徑長度都相等,那么\(1\)到所有可到\(n\)的節點的距離都應該相等,設為\(d_i\),則對於邊\((u,v)\)有\(1\leq d_v-d_u\leq 2\),跑差分約束即可
題解在鏈接里
顯然地貪心,維護一個后綴最小值,如果后綴最小值小於當前的隊尾和隊首,那么就加入隊尾;否則就讓隊尾隊首里較小的出隊
注意到\(m-n\leq 20\),所以我們先求出一棵生成樹,不在生成樹上的邊最多只有\(21\)條,也就最多\(42\)個點,我們用這\(42\)個點構一張完全圖,兩點之間的距離是連接兩點的邊權和兩點樹上距離的最小值,對這張完全圖跑一邊\(\rm Floyd\),每次詢問就枚舉這張圖上的一個點對,統計一下最小值就可以了。復雜度是\(O(n+42q\log n+42^2q)\)
10.18
這題出成這個蛇皮樣子顯然只能暴力,設\(dp_i\)表示以\(i\)為開頭的最長倍數子序列,設\(f_{i,j}\)表示\(i\)后面有多少個轉移點\(k\)滿足\(dp_k=j\),由於最長的子序列是\(\log\)級別的,所以這個數組開的下。在左端插入刪除的是否直接枚舉一波倍數,右端插入刪除就枚舉一波約數搞一個類似bfs的東西就好了;預處理約數表的時候並不需要std::vector<int>
,直接連邊就非常快
之后就荒廢了
10.19
考了個初賽,好像退役了
10.20
下午打了luogu月賽,嚴重降智啥也不會
10.21
不難發現我們需要有一個位移才能通過反復執行這些操作遍歷完整個聯通塊,於是我們枚舉這個位移點,在每個位移點把這個樹切開,對這些切出來的樹求一個交,答案就是\((tot-1-h)\times 2+h\),\(h\)是位移點到根的距離,\(tot\)是交的大小,復雜度是\(O(n^2)\)
10.22
顯然優先滿足美觀值較大的套娃即可,用std::multiset<int>
查前驅的時候可以直接it=s.lower_bound(x)
再把迭代器--
考慮答案長什么樣子,如果最大值和最小值不在端點上,那么區間長度肯定是越短越好;於是我們來個單調隊列先算一遍所有長度為\(L\)的區間的答案,就能包括這種況了;之后是最小值和最大值分別是區間的兩個端點,於是我們枚舉一個\(j\)強行將其視為最大值,直接分數規划一波,轉化成找到一個\(i\)滿足\(L\leq j-i+1\leq R\)且\((a_j-mid\times j)-(a_i-mid\times i)>mid\times k\),還是直接單調隊列即可
對於一條邊\((u,v)\),能被刪除當且僅當存在一個\(x\)滿足\(u\)能到\(x\)且\(x\)能到\(v\),用std::bitset
維護每個點能到達和能被到達的點集,每次拿出兩個bitset
取個與就好了
10.23
斷環為鏈,不難發現答案就是\(n-1+\min_{i=1}^n\{i+\max_{j=i}^{i+n-1}T_j-j\}\),就是枚舉一下出發點\(i\),之后算一下應該在什么時刻出發才能使得走到的所有點的時候都不需要等待,一氣呵成地走完
其實枚舉\(i\)點的時候算的並不一定是從\(i\)出發的最優答案,可能存在一個點\(j\)出現時間非常晚,最優策略應該是先跳過點\(j\),先把后面的點取完,繞一圈回來再取\(j\);用上面的策略算出來的答案顯然偏大了,但對於上面的情況,顯然從\(i\)出發並執行最優策略也不可能是全局的最優解,對於上面那種情況,更優的情況應該是從\(j\)后面的一個點出發,這樣就不需要繞一圈回來了
注意到\(T_i-i>T_{i+n}-(i+n)\),所以我們可以將上面的柿子變成\(n-1+\min_{i=1}^n\{i+\max_{j=i}^{2n}T_j-j\}\),這樣就好看多了。
觀察這個柿子,只有當\(T_j-j\)為后綴最大值的時候才能產生貢獻,而且產生的貢獻就是從前面找到一個最小的\(i\)滿足\(\max_{k=i}^j T_k-k\leq T_j-j\),形成的最小值就是\(i+T_j-j\)
大概是一個類似於單調棧的結構,考慮如何用線段樹合並左右區間;可以維護右區間的最值,在左區間上進行二分,找到最后一個大於右區間最值的位置,中間一路記錄答案即可
10.24
設\(dp_i\)表示\(i\)點子樹中能取到的最大排名,\(sz_i\)表示\(i\)點子樹里葉子節點的個數,當\(i\)為葉子時顯然有\(dp_i=1\);當\(i\)上的操作為取\(\max\)的時候,我們\(dp_i=\max_{i->v}sz_i-sz_v+dp_v\),考慮枚舉把哪一棵子樹的值域分配在最后面;當操作為取\(\min\)的時候,則\(dp_i=1+\sum_{i->v}dp_v-1\),即先給每個子樹一段長度為\(dp_v-1\)的值域,之后再繼續分配就只能分配出最小值了
10.26
顯然選擇的點是直徑的一段,如果有一段不在直徑上的點那么直徑的端點距離這條路徑肯定會更遠;我們把直徑拿出來,對於直徑上每一個點求出掛在上面的最長的鏈,之后單調隊列掃一遍所有長度為\(m\)的區間的最大值就好了,掃出來的最大值記得要跟到直徑兩端點的距離再取一個\(\max\)
跟上面的題好像沒什么區別,換成雙指針來掃,同時維護一個單調隊列
用上面兩道題的方法把直徑求出,如果對於一個直徑上的一個點\(i\),其子樹中的最長連等於點\(i\)到直徑端點的距離,那么\(i\)到子樹中的最長鏈這一段也可以成為直徑,那么\(i\)到直徑端點上的邊就不可能成為被所有直徑都經過了,相當於把公共直徑給削短了一部分;我們對於直徑的兩個端點都這樣掃一遍,最后剩下的就是公共直徑了
把取模拆出來,即求這樣一個式子
如果我們能\(O(1)\)做到查詢\(\sum_{i=l}^rb_{x-i\times k}\)的和,我們就可以整除分塊;這里的\(k\)實際上是\(\lfloor \frac{i}{j} \rfloor\);於是我們根號分治,對於\(j\leq \sqrt{n}\),我們直接暴力;對於\(j>\sqrt{n}\),顯然有\(\lfloor \frac{i}{j} \rfloor<\sqrt{n}\),於是我們提前預處
理一個數組\(g[j][i]\)表示\(i\)往前跳\(j\)步的和,就能\(O(1)\)求解一段的信息了,結合整除分塊,就能做到\(O(n\sqrt{n})\)的復雜度
10.27
一個結論:一個串和其反串的LCS長度等於其最長回文子序列長度,想想就覺得沒啥問題,於是大力區間dp,設\(dp_{i,j,k}\)表示區間\(i,j\)用了\(k\)次修改的最長回文子序列,轉移大概就是\(dp_{i,j,k}=\max\{dp_{i,j-1,k},dp_{i+1,j,k},dp_{i+1,j-1,k-1}+2\}\),當\(s_i=s_j\)的時候,還有\(dp_{i,j,k}=dp_{i+1,j-1,k}+2\)
10.28
設\(f_{n,0/1}\)表示對於一個區間長度為\(n\)的線段樹,根節點沒有/有和其兒子連邊的最大匹配個數,同理在記一個方案數;開個map記搜轉移就好了,狀態數不會超過\(2\log n\)
11.03
剛放完假回來難得有干勁,就寫了點題
一個傻傻的\(O(n^3)\)的dp是\(dp_{i,j}\)表示到了\(i\)個位置搞了\(j\)個箱子的最小花費,顯然這玩意沒法繼續優化;之后發現我們可以直接把序列倒過來,設\(dp_i\)表示到了第\(i\)個位置的最小花費,於是有\(dp_i=pre_i+dp_j+\max_{k=j+1}^ia_k-\min_{k=j+1}^ia_k,pre_i-pre_j\leq W\),相當於把一個箱子的貢獻分開算了;我們發現這個\(dp\)可以使用單調棧+線段樹來優化,於是就做完了
策略比較顯然,優先去掉割邊,去掉一條割邊就會增加一個聯通塊;之后發現對於一個大小為\(L\)的話,想增加\(i\)個聯通塊需要去掉\(i+1\)條邊,於是把所有環從大到小排序,之后順着割過去就好了
因為仙人掌上每一個環都是一個點雙,所以我們可以大力\(\rm tarjan\)找到所有點雙,剽了個點雙板子,發現挺好背的
普及的題有質量多了,考慮到或和與最后的結果就是一些二進制位相加,於是可以直接枚舉兩個二進制位\(i,j\),求有多少條路徑滿足與在\(i\)位上是\(1\),或在\(j\)位上是\(1\),把這樣的路徑條數乘\(2^{i+j}\)累加進答案即可
11.04
把相鄰兩個金幣之間的空位看成石子,發現是一個倒着的階梯Nim;於是只有奇數層的石子是有用的,我們只算奇數層的情況,偶數層用組合數分配一下就好了;顯然一共有\(m+1\)層,則一共有\(\lfloor \frac{m+1}{2} \rfloor\)個奇數層
先手必敗的條件是異或和位\(0\),即每一位上都是偶數個\(1\);於是我們可以按位考慮,設\(f_{i,j}\)表示奇數層從分配了\(i\)顆石子,已經考慮完了第\(j\)位,我們枚舉當前這一位上所有多少個\(1\),用組合數把這些\(1\)分進去就好了,即\(f_{i,j}=\sum_{k=0}\binom{\lfloor \frac{m+1}{2} \rfloor}{2k}\times f_{i-2^i\times 2k,j-1}\),直接暴力轉移即可;復雜度是\(O(nm\log n)\)
設\(dp_{i,j}\)表示把\(s\)的前綴\(i\)分成\(j\)段最多能匹配到\(t\)串的位置;轉移有兩種,一是\(s_{i+1}\)不選,即\(dp_{i,j}\)向\(dp_{i+1,j}\)轉移;還有一種是\(s_{i+1}\)選,顯然我們應該盡可能地往長里匹配,設\(l=\rm LCP(s_{i+1},t_{f_{i,j}+1})\),即\(dp_{i,j}+l\)向\(dp_{i+l,j+1}\)轉移
11.05
設\(dp_{i,j}\)表示插入了前\(i\)種顏色,有\(j\)對相鄰的且顏色相同的格子;對於當前要插入的顏色\(i\),我們發現把其分成\(k\)段,內部形成的相鄰相同顏色對數就是\(c_i-k\);如果之前形成的對數為\(j\),把\(i\)顏色分成\(k\)段,我們枚舉一下其中\(p\)段插入到那\(j\)段相鄰且顏色相同格子之間,那么新的對數就是\(j+c_i-k-p\),從\(j\)對里選\(p\)個,再從剩下的\(n+1-j\)個空位之間選\(k-p\)個,把\(c_i\)中顏色分成\(k\)段,這要乘上一堆組合數,大概是\(\binom{j}{p}\times \binom{n+1-j}{k-p}\times \binom{c_i-1}{k-1}\)
11.06
根號分治一下;對於\(i\leq \sqrt{n}\)的物品,這顯然是一個多重背包,設\(f_{i,j}\)表示前\(i\)個物品選的體積為\(j\)的方案,\(f_{i,j}=\sum_{k=1}^if_{i-1,j-k\times i}\),我們發現這個東西放到\(\mod\ i\)意義下能前綴和優化,於是這邊的復雜度是\(O(n\sqrt{n})\)
注意到對於\(i>\sqrt{n}\)的物品來說,數量限制其實沒有用的,等價於一個完全背包;由於物品的體積都大於\(\sqrt{n}\),所以背包中的物品個數不會超過\(\sqrt{n}\)件,設\(g_{i,j}\)表示背包中有\(i\)件物品體積為\(j\),我們有兩種操作,一種是加入一個體積為\(\sqrt{n}+1\)的物品,一種是所有物品題積加\(1\),不難發現我們通過這兩種操作能構造出所有符合條件的狀態,於是有\(g_{i,j}=g_{i-1,j-\sqrt{n}-1}+g_{i,j-i}\),這邊的復雜度也是\(O(n\sqrt{n})\)
11.09
計數轉一下概率,視為每次操作等概率發生,即求極長連續段個數的期望乘上\(2^i\)即可
考慮對於一個給定的情況,如何計算極長連續段數目,可以在每個極長連續段開始的時候計算貢獻,即\(1+\sum_{i=2}^n[a_{i}\neq a_{i-1}]\),於是設\(f_i\)表示\(a_{i}\neq a_{i-1}\)的概率,我們要求的即\(1+\sum_{i=2}^nf_i\);考慮對於一個修改操作\([l,r]\),如果發生,那么\(r+1\)和\(l\)肯定和上一個數不一樣了,於是\(f_{l}=\frac{1+f_{l}}{2},f_{r+1}=\frac{1+f_{r+1}}{2}\);對於\(i\in [l+1,r]\),如果這次操作發生那么\(a_i\)就會等於\(a_{i-1}\),於是有\(f_i=\frac{f_{i}}{2}\)。於是直接暴力過去就能做了
先跑個tarjan縮一下強聯通,對於一個強聯通分量,我們記下這個強聯通分量里的最大邊權和最小邊權;搞一個拓撲求一下\(1\)號點到所有強聯通分量的最大邊權和最小邊權;答案是一個極差,所以討論一下最大值和最小值來自哪里,最大值和最小值來自強聯通分量內部都很好算;考慮最大值和最小值都來自\(1\)到這個強聯通分量\(v\)路徑上的情況,現在有一個和\(v\)直接連邊的\(x\)要向\(v\)轉移,如果最大值和最小值都在\(1\)到\(x\)的路徑上,那么我們直接讓\(v\)繼承\(x\)的答案就好了;也有可能\(x\)到\(v\)這條邊的成為了新的最大值或最小值,還是拿\(x\)的最值討論一下就好了
轉移大概是這么寫
dp[v]=max(dp[v],dp[x]);
dp[v]=max(dp[v],max(max(dp_mx[x],e[j].w),mx[v])-min(e[j].w,mn[v]));
dp[v]=max(dp[v],max(e[j].w,mx[v])-min(min(dp_mn[x],e[j].w),mn[v]));
11.10
觀察一波發現肯定是\(a\)序列中的連續一段對應了\(b\)序列中的一個位置,且這些對應關系兩兩不交;比如一個\(a\)序列1 0 1 0 1
一個\(b\)序列2 0 1 0 0
就是1 0 1
對應了2
,0 1
對應了1
;對應關系不相交也是比較顯然的,因為相交的對應關系根本沒有辦法合並過去;於是我們存一下\(b\)中的非\(0\)位置,之后掃\(a\)序列,一旦掃到一段和等於\(b\)中那個待匹配的數,就匹配過去,如果位置相等就不需要花費代價,否則就要花費\(1\)的代價
由於邊權都是\(2^i\),所以最短路需要最小化最大邊權,最小化次大邊權......於是這就是一棵最小生成樹,建出樹來求個lca就沒了
隨便推一波式子發現答案就是\(\frac{1}{4}\sum_{i=1}^n a_i\times (\frac{3}{4})^{i-1}\),這里的\(a\)是從大到小排好序的序列,於是隨便用線段樹什么的維護一下就好了
考慮一個暴力,我們用小根堆維護目前前\(k-1\)大的數,每加進來一個數就把堆頂彈出去插入新序列的末尾,這樣的復雜度是\(O(ans\times n\log n)\)
考慮這個暴力的一些性質,發現對於一個數\(a_i\),如果前面比它大的數不超過\(k-1\)個,那么這些數都會被移動到他后面去;否則就只能移動\(k-1\)個,設\(b_i\)表示\(i\)前面大於\(a_i\)的數的個數,答案就是\(\lceil \frac{\max b_i}{k-1}\rceil\)
對於一個點\(i\),我們將其換到\(x\)的位置上,發現點權變成了\(a_i-dep_i+dep_x\),於是我們定義\(b_i=a_i-dep_i\),現在我們要做的就是把這些點權分配到樹上,使得每個點點權+深度不小於子樹內點權+深度
首先對於根節點,我們肯定要分配點權最大的點,如果點權最大的點有多個,那么我們把哪一個放到子樹中都會使得它比根更大,所以無解;之后考慮一條鏈的特殊情況,我們發現,如果有兩個點權相等的點,那么無論哪個點在下都會大於在上面的點,於是也無解;擴展到多條鏈,我們發現點權相等的點不能超過支鏈個數,否則一定會出現兩個點權相等的點成為祖先關系,於是只需要判斷點權相等的點和支鏈的大小關系即可
11.12
如果輸入的兩個編號中較大的那個不是\(n\),那么就直接GG了;否則,我們考慮把\(n\)作為根,之后瞎構造;不難發現構造一條鏈一定是最優的,於是直接莽過去就沒了
求一下直徑,顯然我們應該盡量留着直徑的兩個端點,優先刪掛在側鏈上的葉子;把側鏈刪完之后在刪掉直徑就好了
把邊和詢問都排序之后離線,維護每個聯通塊大小的平方和就好了
用權值線段樹維護修改,每次在權值線段樹上二分找到最后一個\(ih_i-\sum_{j=1}^ih_j\leq v\)的位置就好了