【2021~2022】模擬賽亂寫 Period I


ZZH與計數

因為題目里面所涉及的操作和每個 \(1\) 的位置沒有關系,只與數量有關,那么設 \(f_{r,a,b,i,j}\) 表示原先有 \(a\)\(0\)\(b\)\(1\),在進行 \(r\) 次操作之后有 \(i\)\(0\) 變成了 \(1\),同時有 \(j\)\(1\) 保持不變

轉移是相對容易的:考慮這一次選擇的操作對數字中 \(0/1\) 數量的影響

  • 選擇用超集減少 \(1\) 的個數來轉移,概率是 \(p\),方案如下:

    \[\sum_{x=i}^{a}\sum_{y=j}^bf_{r-1,a,b,x,y}\frac1{2^{x+y}}\binom{a-i}{x-i}\binom{b-j}{y-j} \]

  • 選擇用子集增加 \(1\) 的個數來轉移,概率是 \(1-p\),方案如下:

    \[\sum_{x=0}^i\sum_{y=0}^jf_{r-1,a,b,x,y}\frac1{2^{n-x-y}}\binom ix\binom jy \]

直接枚舉 \(a+b=n\) 的部分然后對 \(r\) 進行矩陣快速冪即可

這部分復雜度為 \(n^7\log m\),但是注意到合法的 \(i,j\) 狀態總和在 \(\frac{n^2}4\) 左右,那么成功帶了 \(\frac{1}{64}\) 的常數,甚至更小

剩下的部分枚舉 \((s,t)\) 直接上式子復雜度是 \(2^{2n}\) 不能通過,那么考慮對這部分進行 \(\rm{DP}\)

\(g_{i,S,a,b}\) 表示當前考慮到了二進制下 \(i\) 位,當前得到一個數字 \(S\),但還需要讓 \(i\) 為從 \(0\) 變成 \(1\),有 \(j\) 位從 \(1\) 變成 \(0\)

初態是

\[g_{0,S,i,j}=v_S\times f_{m,C(S),i,C(S)-j} \]

其中 \(C(S)\) 表示 \(S\) 的二進制表示下 \(1\) 的個數

最后一維的含義是如果要最后有 \(C(S)-j\)\(1\) 被保留的話現在就需要有 \(j\)\(1\) 被刪除,恰滿足等式左側的含義:需要有 \(j\)\(1\) 變成 \(0\)

這里並不需要讓 \(S\)\(t\) 后面的二進制位下都滿足是 \(0\),這個東西轉移直接考慮修改當前二進制位的值即可

貌似需要調整 \(g\) 數組的維度順序來減少取址用時

T4顯然也是我整的

為了書寫方便,以下將集合 \(S\) 中元素分配下標,\(G\) 表示集合 \(S\) 中元素的最小公倍數

觀察到 \(n\)\(\max\limits_{x\in S}\ x\) 大很多時,答案為 \(\rm{GCD_{x\in S} x}\),下證最大值上界為 \(\frac n2\)

\(\forall\ x\in S,x\le m\),不難根據 \(\rm{Exgcd}\) 寫出方程:\(\sum\limits a_iS_i=G\),其中 \(a_i\) 是分配的系數,帶標號

考慮一個包含 \(a_i\) 個有標號 \(S_i\) 的多重集,如果 \(a_i>0\),則多重集中有 \(a_i\)\(S_i\),反之包含 \(-a_i\)\(-S_i\),設位移 \(v\) 初始為 \(1\),每次可以向其加入一個多重集中的元素,需要保證 \(v\in [1,n]\)

  • \(v\le m\)

    此時不一定存在一個 \(S_i< v\) 但是一定有一個 \(S_i\le m\) 滿足 \(S_i+v\le 2m\)

    可以據此約束 \(m\) 的上界:\(2m\le n\to m\le \frac n2\)

  • \(v>m\)

    那么一定可以找到一個 \(-S_i\) 滿足 \(v+(-S_i)\ge 1\),因為如果沒有負位移,根據方程 \(\sum a_iS_i=G\le m\)

如果一個局面中 \(S\) 中元素均大於 \(\frac n2\),那么存在一些點不能和任何點連邊,設 \(mn\) 表示集合最小值,則這樣子點的數量為 \(2mn-n\) 個,可以把它們直接加到答案中,並將長度及 \(S\) 中元素減去 \(2mn-n\),變成一個子問題,推導可以發現此時集合中存在小於等於半倍長度的元素

那么可以將此時所有 \(\le \frac n2\) 的元素取出並求出 \(\rm{gcd}\) 設為 \(d\),剩下元素能作為合並集合的是那些 \(d+S_i\le n,S_i\ge \frac n2\) 的部分

這些元素能跨過並合並所有現存集合,可以直接 \(d\leftarrow gcd(d,S_i)\),不難發現直接按照從小到大的順序掃描所有 \(S_i\) 就能完成全部合法元素的合並,因為取 \(gcd\) 會讓 \(d\) 不增

當前狀態下最后沒有被處理貢獻的元素是 \(S_i>\frac n2,S_i+d>n\),而且數量很少,可行邊的左端點在 \([1,n-S_i] (n-S_i<d)\) 中,此時可以保留 \(d+n\%d\) 長度的線段,即在同余意義下分組,並將這些未處理的 \(S_i\leftarrow S_i+nlen-n\),此時變成原問題子問題,可以遞歸處理

注意 \(d\) 也要放到新集合中以防 \([i,i+d]\) 這樣的同余組被重復記

每個元素最多被降值 \(\log\) 次,每次處理最多有 \(\Theta(1)\) 個元素沒有被降值,附加排序的復雜度,總復雜度 \(\Theta(m\log^2n)\),常數小到跟乘 \(\frac1{\log n}\) 一樣

游戲

由於每個長度 \(K\) 對應的總方案數是確定的,那么得到每個情況的方案數就能得到答案

考慮對於每個長度計算在 \(A\) 中選出子串 \(X\) 的字典序不大於 在 \(B\) 中選出的子串 \(Y\) 的方案數,再算出來 \(\rm{Ord(X)\ge Ord(Y)}\) 的方案數,兩者求和減掉總方案即平局方案

不難發現要處理 \(X=Y\) 的情況這就是 \(LCP\),套路地使用 \(SA\):考慮對串\(A* B\) 構建后綴數組

對於每一個屬於 \(A\) 的后綴,排在它后面的屬於 \(B\) 的后綴和它產生的貢獻是 \(1\sim min(len_A,len_B)\) 長度的答案均 \(+1\)

如果進行后綴排序之后按照 \(sa\) 的順序處理所有下標,並對每個長度維護權值,如果是 \(B\) 的后綴就讓 \(1\sim len\) 的權值增加 \(1\) 而遇到 \(A\) 中的后綴讓權值加到對應長度的答案中去

對於在 \(SA\) 序上的逆序對,對不大於的貢獻還可以是等於,這可以用 \(\rm{height}\) 上類似的方式來維護

從前往后,在遇到 \(B\) 的后綴時,將 \(1\sim len_B\) 的貢獻 \(+1\),遇到每一個 \(height\) 都將大於 \(height\) 的貢獻清零,遇到一個 \(A\) 的后綴 ,就將 \(1-height_A\) 的貢獻加進對應長度的答案

這時候那么需要一種維護兩個權值的數據結構,滿足可以讓其中之一加 \(1\),還可以讓一個加到另一個上去和清空其中之一

使用行向量 \(\rm{[1,dlt,ans]}\) 表示每個長度對應的信息,那么加一、清空,加到答案中去分別對應三個 \(3\times 3\) 的矩陣,直接用線段樹維護所有區間矩陣乘法即可

注意這里不可以標記永久化,因為矩陣乘法沒有交換律

到這里不能通過,因為矩陣乘法復雜度高,但是觀察發現第一行和最后一列只有兩個 \(1\),而且在進行乘法的過程中這個性質一直滿足,那么只需要維護右上角的 \(2\times2\) 的部分即可

矩陣乘法復雜度降到了 \(4\),可以通過

石子游戲

每堆石子互相獨立,局面是否滿足先手必勝等價於 \(xor_{i=1}^n\ SG_x(a_i)>0\)

根據定義大力手玩可以得到 \(SG_k(x)=x\% (k+1)\),那么問題轉化成了求一堆數模特定數的異或和

由於是取模運算,可以使用 \(x\%y=x-\lfloor \frac{x}y\rfloor\times y\) 來進行第一步轉化

又出現了熟悉的除法,那么明示調和級數,同時剩下的問題為統計 \([ky,(k+1)y)\) 中的數在每一位下的貢獻

先設 \(cnt[l,r,j]\) 表示 \([l,r]\) 中的數字 \(x\) 滿足 \(x-l\)\(j+1\) 個二進制位下為 \(1\) 的堆的數量

可以先對題目中給出的 \(c_i\) 求前綴和,同時預處理 \(f_{i,j}\) 表示滿足 \(x-i\) 在第 \(j+1\) 個二進制位下有數的堆的數量

求解 \(f\) 非常容易:只用考慮 \(i\) 及其后面 \(2^{j+1}\) 個數中的狀態,剩下的用 \(f_{i+2^{j+1},j}\) 統計

不難觀察到對一個 \(f_{i,j}\) 貢獻的一定是一段一段的 \(c_i\) 的和的形式

那么求一個 \(cnt[l,r,j]\) 只需要找到最后一個 \(pos=l+k2^{j+1}\le r\) ,並將后面的數字刪去,再使用前綴和把 \([pos+2^{j},r]\) 中數字補回來就行了

本題可以大力剪枝:發現對於一個模數如果在一個二進制位下余數有貢獻的數的數量是奇數,那么異或和必然不為 \(0\) ,后面的二進制也不用再找了

古老的序列問題

先分治,將詢問掛到線段樹節點上面:如果跨過節點中點則和朴素分治類似,完全覆蓋者和線段樹區間查詢類似

考慮跨過區間中點 \(mid\) 的詢問的回答,做法仍然是維護每個區間右側點的歷史答案和,在左端點處統計貢獻

觀察答案增量的表現形式:區間的最大值乘最小值,信息可能分布在 \(mid\) 的左右兩側,分類討論

不難發現左邊 \(\min\) 函數單調遞減,\(\max\) 函數單調遞增,使用左邊 \(\min\) 作為區間 \(\min\) 的區間單調右移,\(\max\) 同理,可以用兩個單調指針得到

剩下的就是線段樹維護了,需要寫出 \(4\) 個懶標記,不過互相獨立,只是稍微打打字而已

為什么有老哥能會 \(\Theta(n\log n)\) 高論呀?

記憶碎片

觀察最小生成樹的 “生成” 過程:中間態可以表現為一些大小和為 \(n\) 的聯通塊

如果忽略聯通塊上點的標號,狀態可以表示成一個 \(n\) 的划分

本題中 \(n\) 的數量級比較小,可以直接 \(dp[i][S]\) 表示加入了 \(n^2\) 條邊中的 \(i\) 條之后狀態成 \(S\) 的方案數

那么轉移簡單得離譜:

  • 如果當前邊不在最小生成樹上那么只能在聯通塊里面補邊,這里需要統計每個狀態中聯通塊連滿能用多少邊

  • 在最小生成樹上的邊需要合並聯通塊,暴力枚舉狀態里面的就行

復雜度是 \(\Theta((n^2)P(n))\) 的,可以通過

置換

首先發現

\[f(P)=\rm{LCM}_ {R\in P}\ Len(R) \]

其中 \(R\) 表示置換環,\(Len(R)\) 表示 \(R\) 置換環的長度

還是寫出答案的直接表達式:

\[\sum_{\sum x_i=n}\frac{n!}{\prod x_i!}\prod (x_i-1)! \frac{1}{\prod y_i!} \]

這里 \(y_i\) 表示 \(x_k=i\)\(k\) 的數量,式子最開始是多重集排列,中間是不同長度置換環數量,最后去除重復

直接沖整數划分復雜度甚至跑不動 \(n=100\),只好寫出 \(\rm{DP}\) 式子:\(f_{i,j}\) 表示選出的數字和為 \(i\)\(\rm{LCM=j}\) 的方案數

所有可能作為最小公倍數在滿數據范圍內有八十來萬,考慮分質因子中是否含有 \(>\sqrt n\) 來處理:

如果只計算質因子不超過 \(\sqrt n\) 的數字的最小公倍數只有兩千來種,數量級可以接受,那么將 \(>\sqrt n\) 的數字作為方案數存下來

注意到每個不超過 \(n\) 的數包含的 \(\sqrt n\) 的質因子個數和次數均不超過一

對於質因子小那些還是執行上面的算法,存在大質因子的數,作為置換環長加入時將大質因子 \(P\) 乘當前的方案數加入原方案數即可

B關系

稍微花時間編一個(假的)\(\Theta(n^3)\)\(\rm{DP}\) 可以發現 \(n\) 需要矩陣快速冪,而 \(R\) 是作為矩陣中的系數來求解

優化是一種叫做 \(\rm{DP}\)\(\rm{DP}\)\(\rm{trick}\)

題目中要求 \(\rm{LCS}\) 要不小於序列長度減 \(2\),回看朴素的 \(\rm{LCS}\) 轉移,存儲兩維差大於 \(2\) 的狀態對最終答案求解無意義

那么計算 \(f_{n+1,n+1}\) 只需要 \(f_{x,y}[\exists\ x,y=n][\forall \ x,y\ge n-2]\) 的值和 \(A[n-1],A[n],B[n-1],B[n]\) 四對的相等關系

實現的時候存 \(\rm{DP}\) 值用類似 \(n-f_{n,n}\) 的方式進行存儲值,然后把這些需要求的 放到結構體里面做就行

對於相等關系將序列里面的四個值隨便賦一些 \(\le 4\) 的值放起來,注意要滿足最小值是 \(1\) 且值域連續

那么先給 \(A[1],A[2],B[1],B[2]\) 隨便賦值搜出來所有 \(n\le 2\) 的合法狀態,每個狀態可能的方案數是 \(\binom R {num}\),其中 \(num\) 表示四個的里面最大顏色

對於狀態之間的轉移建立基矩陣,兩個元素之間的轉移不是一對一對枚舉,而是實地枚舉 \(A[i+1],B[i+1]\) 的值,注意這兩個量可以枚舉到 \(num+1,num+2\)

同上,還是不關注具體是誰,還是只關注相等關系,轉移方案數如下:

  • \(A[i+1],B[i+1]\le num\) 顏色固定,系數為 \(1\)

  • 二者其一大於 \(num\),或者兩者都大於 \(num\) 且顏色相同,選擇方式只能是在 \(R-num\) 中選一個

  • 都大於 \(num\) 且不同,那么是 \(\binom{R-num}2\)

注意顏色的離散,每個狀態里面的顏色 標號 不能大於 \(4\),而離散化方式非常離譜,不同的方式導致狀態數量差異巨大,按照 \(A[0],B[0],A[1],B[1]\) 的順序用逐次加入 std:map 可以做到 \(200\) 左右的數量級

實現兩個狀態對應的結構體轉移是容易的,使用朴素 \(\rm{DP}\) 的轉移式子完成即可,注意如果被轉移者 \(f_{n,n}\ge3\) 則新的狀態無意義

另注意狀態可能不止搜出來的那些,會動態添加一些

最后寫一個矩陣快速冪即可

黑白

又一次學習 \(\rm{SG}\) 函數

預處理 \(f_{o,z,s}\) 表示有 \(o\)\(1\)\(z\)\(0\) 的序列中 \(\rm{SG}=s\) 的方案數,那么計算概率,總方案是 \(\binom{o+z}z\)

轉移考慮枚舉添加 \(x\in[0,100-z]\)\(0\) 和一個 \(1\),手動模擬序列 \(\rm{SG}\) 值就知道是轉移給 \(f_{o+1,z+x,x+(s\le x)}\)

具體而言,每個非末尾 \(1\)\(\rm{SG}\) 值必然是 \(0\),其余點的 \(\rm{SG}\) 值的后繼為拿掉能拿掉的數字后能走到的點的 \(\rm{mex}\)

之后做一個 \(g_{i,j}\) 表示到第 \(i\) 個序列,異或和為 \(j\) 的概率,轉移是 \(\rm{FWT}\) 狀物 的 \(\rm{DP}\) 就行了

不難想到對模數進行根號分治:

  • 對於模數不大於 \(\sqrt n\) 的部分,枚舉每個模數和余數

    將詢問點,修改點的深度對模數取模,分開每個 \(\texttt{(模數,余數)}\) 處理,這樣進行子樹區間加法並不會對其它詢問產生影響

    每個詢問對每個模數都要查,那么有 \(q\sqrt{n}\) 次查詢,每個修改的模數余數固定,那么只有 \(q\) 次修改

    使用一個 單點查詢,區間修改 的分塊即得到 \(\Theta(q\sqrt n)\) 的復雜度

  • 對於模數大於 \(\sqrt n\) 的部分,求出每個修改對哪些深度有影響

    枚舉深度統計答案,修改拆成了 \(q\sqrt n\) 次,每個詢問有特定深度,那么要進行 \(q\) 次查詢

    這時候可以使用一個 區間查詢,單點修改 的分塊進行子樹加法,復雜度 \(\Theta(q\sqrt n)\)

本題使用根號分治后巧妙使用根號平衡優化了復雜度,值得一想

萬豬拱塔

考慮判斷一些格點能否構成一個矩形的方式:

將矩陣擴展成 \((0,0)\to (n+1,m+1)\) ,每個 \(2\times 2\) 的小矩形的起始點為 \((0,0)\to (n,m)\)

將選定格點染成黑色后,如果這些小矩形中黑色點個數為 \(3\) 的格子數量為 \(4\) 且不存在黑色格點為 \(1\) 的小正方形則構成一個矩形區域

正確性是顯然的

用線段樹維護 \(f(l,r)\) 表示區間中的點染成黑色后滿足格子里面點數為奇數的格子數

不難發現加入一個點后,黑色格點奇偶性變化的格子只有相鄰四個,分開處理變化,即對於每個小矩形分段修改貢獻

抑郁刀法

不難發現原圖中 \(num\) 個一度點對答案的貢獻是乘 \((k-1)^{num}\),那么可以把這些點縮起來

剩余的二度點 \(x\) 連向 \(a,b\),刪去其后給 \(a,b\) 連一個新邊,如果 \(a,b\) 同色,\(x\)\(k-1\) 種選擇,而 \(a,b\) 異色有 \(k-2\) 種選擇

\(f(a,b)\) 表示 \(a,b\) 同色的附加貢獻,\(g(a,b)\) 表示異色,初始化 \(f(a,b)=0,g(a,b)=1\)

如果合並兩個帶權邊則考慮實際含義即可轉移(\(f=f_1f_2+(k-1)g_1g_2,g=g_1f_2+g_2f_1+(k-2)f_1f_2\)

照着轉移可以把 \(2\) 度點刪掉,剩下的三度點 \(n\le 10,m\le 15\) 可以使用 \(DP\) 維護

轉移考慮添加一個集合表示集合里面的點選擇同一個顏色,需要添加一維狀態表示選的顏色數,最后需要乘組合數

實現起來細節龐雜,其一是重邊不是合並來的,而是乘起來的

seat

每個人對應的最大長度長度是一定的,同時經過若干人后剩余線段的可重集是一定的

由此不難發現一個最大長度對應的人是一個區間

每個長度為 \(n\) 線段每次會被分成 \(\lfloor\frac{n}2\rfloor,\lceil\frac n2\rceil\) 兩個,那么我們發現不同的最大長度只有 \(\Theta(\log n)\) 種:\(\lfloor \frac{n}{2^k}\rfloor,\lceil\frac n{2^k}\rceil\)

下文把這樣的每個最大長度對應的連續區間成為一個段

注意到對於長度為偶數的區間和長度為奇數的區間並不等價,所以要求出每個段中偶數長度區間個數

考慮對一個特定的最大長度求出每個位置的概率,設 \(dp_{i,j}\) 表示取出 \(i\) 個區間,剩余 \(j\) 個長度為偶數的區間

轉移考慮有剩余哪些轉移點來計算當前選奇數/偶數的概率,這個 \(\rm{DP}\) 是問題的關鍵

最后需要將偶數區間帶來的概率進行平均,因為前面對區間長度有影響,但是對選擇位置是等概率的

實現的時候用優先隊列維護可重集合來求每個最大長度對應多少個小 \(\rm{G}\),不難發現偶數長度區間會被先取出,所以計算偶數長度時會稍方便

回文串

首先有"本質不同的回文串的數量級是 \(O(n)\) 的"

證明很簡單,考慮sam上最多有 \(2n-1\) 個節點,同時這些節點中每個最多有一個回文串

(如果有多個的話,那么短串的 \(endpos\) 比長串要多)

其實在這個題目里面關注的是 \(midpos\),那么給所有的回文串標號

\(manacher\) 處理所有的回文中心,把短串向長串連邊得到一個樹

對於每次處理的 \(id[i-r[i]+1,i+r[i]-1]\) 異或上 \(i\) 最后按照 \(SAM\) 維護 \(endpos\) 個數那樣維護 \(midpos\) 的異或和即可

復雜度 \(\Theta(n)\)

整除

先把 \(x=1\) 的判掉,注意這里應該是系數和是 \(m\) 的倍數

使用等比數列求和公式把原多項式乘上 \(x-1\),然后使用多項式取模把原多項式次數降到 \(m\) 以下,設此時 \(R(x)=\sum a_i x^i\)

關於多項式取模的部分,對於每個 \(a_ix^i\),給 \(x^{i\%m}\) 貢獻 \(a_i\) 的系數

此時如果余多項式為 \(0\) 則有無窮解,反之解不會大於 \(\max\{a_i\}\)

那么題目轉化為帶入一個 \(x\) 判斷多項式模 \(x^m-1\) 是不是滿足系數均為 \(0,-x+1,x-1\)

后面兩個系數的取值可以使用等比數列求和得到一個倍數的形式

使用 \(set\) 找到當前所有大於等於 \(x\) 的系數,按照高精度數計算的思想進行 "進位" 即可

考慮到 \(\sum a_i\)\(O(n)\),不斷減得到一個調和級數的復雜度,套上 \(set\),那么總復雜度 \(\Theta(n\log^2n)\)

詞典

考慮到這個模式很像一個 \(trie\) 樹刪兒子的模型,那么設計一個 \(f_i,g_i\) 表示左/右子樹選 \(i\) 個的最小代價,轉移想想就有了

考試的時候看着 \(O(n)\) 的部分分就打了個表發現轉移點最多差 \(1\),卡了卡空間得到了 \(50\)

大力打表發現 \(f(i)-f(i-1)\) 單調不增而且都非常小,那么盲猜可以預處理每個 \(x\)\(f(n)-f(n-1)=x\) 最大的 \(n\),查詢時二分

  • \(f(n)\) 是凸函數:使用右下凸包和右下凸包的閔可夫斯基和就是 \(min-add\) 卷積

  • \(f(n)-f(n-1)\)\(\log^2n\) 級別的數,這個貌似用二叉樹對應深度上的點就能證明

那么可以倍增套二分得到 \(x\) 的界點,注意實現的時候需要 \(1.5\) 倍倍增,三分 \(f(i)\) 的轉移點的時候把下界設成 \(\frac i3\)

做法貌似神乎其神,其實是一點沒懂……學到了 \(1.5\) 倍倍增來卡常?

未來拼圖

不難發現是個循環卷積,那么直接想就知道是多項式開根

那么 \(\rm{FFT}\) 已經是循環卷積了,所以直接 \(\rm{DFT}\) 之后點值開根再 \(\rm{IDFT}\) 回來是正確的

直接給復數開根會得到兩個結果,硬上枚舉是 \(2^n\) 的,並不能通過

但是發現 \(P_i=P_{n-i}\),這樣子只要枚舉一半的根的選擇,對稱的部分跟着選

注意到這里 \(n=25\) 並不是 \(2\) 的整次冪,同時它也很小,那么直接 \(\Theta(n^2)\) 帶入 \(\omega_n^i\) 進行點值計算和插值還原

實現注意以下:

  • 復數開根結果可能相同,所以得到的多項式要去重

  • \(n^2\) 卷積得到結果來判定合法

  • 注意 \(P_i\) 是非負整數,\(\rm{IDFT}\) 得到負值的時候要舍去

  • 注意 \(P_i=P_{n-i}\),所以枚舉一半這里勢必有細節

最大價值

看看這個部分分設置想到了大力 \(\rm{EK}\) 和模擬費用流,都和正解沒有關系但是啟發是不是代價有凸性

寫了個暴力發現還真能滿足 \(k\) 大小的集合 是 \(k+1\) 大小的集合的子集,那一看就是一個 \(\rm{Insertion}\) 的東西

結果做了一場也沒看出來咋維護,愣沒看出來整差分表

問題寫成 \(\rm{DP}\) 就是 \(\rm{f_{i,j}=\max\{f_{i-1,j},f_{i-1,j-1}+a_i\times (j-1)+b_i\}}\)

如上所說,如果在某個位置 \(k\) 加入一個元素,其對差分表的影響是后綴加 \(a_i\),對應點加 \(a_i(k-1)+b_i\),前綴不變

按照上述定義寫出對應的轉移方程不難得到

那么按照 \(a_i\) 從小到大排序加入平衡樹即可

大水題

先對序列求前綴和

如果直接給定一個區間,判斷若干種牛出現次數出現次數相同的方式是取出這些種類的點值差分,如果差分表對應那全相同則出現次數相同

這種做法正確性不難自證,但直接應用到本題中,即使用 \(\rm{hash}\) 表維護狀態對應做端點 時間復雜度達到了 \(\Theta(\rm{maxb\ 2^{\rm{maxb}}n})\)

真的需要對所有的 \(2^{\rm{maxb}}\) 種 種類搭配方式都枚舉一次嗎?

對於一個固定區間右端點,在左端點從右往左挪的過程中,牛出現的種類數只會變化 \(\rm{maxb}\)

那么對於枚舉的右端點,動態維護每個左端點到當前右端點的牛的出現集合

不難發現每次只需要修改 \([\rm{lst[a[i]],i-1}]\) 中的點作為左端點時的出現牛的狀態集合,伴隨狀態集合的變化,對應的差分表也會增加數字

這部分會遍歷 \(\rm{maxb}\) 次數組,復雜度比較優秀

那么在 unordered_map 中把不合法的狀態左端點改成 \(-1\),把當前的牛的集合加入即可

更新答案考慮按照上一次出現的位置增加進入狀態再去哈希表里面查即可

這樣的話復雜度是 \(\Theta(\rm{maxb^2n})\) 不可避免地帶了 \(8\) 的常數,但是比 \(256\) 好多了

佛羅里達

面向范圍編程可以發現正解復雜度在 \(\Theta(n^3)\) 左右,那么直觀的想法就是枚舉所有邊作為一個集合的最大邊

不妨設 \(\max(A)\le \max(B)\),那么枚舉 \(B\) 之后答案必然有單調性,

那么先二分 \(A\) 的權值,然后判斷是否可行是一個明顯的 \(\rm{2-sat}\)

  • 對於那些 \(v\le \max(A)\) 的邊沒有限制

  • 對於那些 \(\max(A)<v\le \max(B)\) 的邊不能都在集合 \(A\) 中所以分別連向對方的逆命題即可

  • 對於 \(v>\max(B)\) 的情況,那么除了上面的邊以外,逆命題連反向邊

至此得到了 \(\Theta(n^4\log n)\) 的做法,基本功扎實的話可以一兩分鍾想到

和上一題一樣,請問:真的有必要枚舉所有邊作為 \(\max(B)\) 嗎?

考慮對完全圖求一個最大生成樹,黑白染色后,如果 \(B\) 集合包含兩種顏色的點,那么集合最大邊一定在最大生成樹上面

首先 \(B\) 集合包含的點在生成樹上距離不能都超過二,否則 \(\max(A)>\max(B)\)

如果距離都等於二那么都是同一個顏色

至此證明了如果集合包含兩種顏色的點,那么 \(\max(B)\) 一定在最大生成樹上

這樣子只需要枚舉 \(O(n)\) 級別的邊就能覆蓋這部分,剩下的是在染色之后黑色點一個集合,白色一個,分別枚舉即可


免責聲明!

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



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