寒武紀camp Day4
補題進度:7/10
A(博弈論)
略
B
待填坑
C(貪心)
題意:
一個序列是good的當且僅當相鄰兩個數字不相同。給出一個長度為n的數列,每個數字是ai。定義一種操作就是把a中某個元素拿到首位去,問最少需要多少次操作才能讓數列a變成good的。如果不可行則輸出-1。
n<=1000,1<=ai<=n
分析:
我們先來判-1的情況,當且僅當出現次數最多的那個數字的出現次數超過了$\frac{n}{2}$
然後我們再來考慮一般的情況,我們把那些需要移動的數字全部拿出來記錄一下,即b[i]表示至少要把b[i]個數字i提到前面去
假設目前一共要移動m個數字,那麽如果出現次數最多的數字的出現次數不超過$\frac{m}{2}$,那麽是很美好的,因為這樣我們一定可以用m此操作讓它們跑到前面去並且不沖突
但是如果出現最多的次數超過了$\frac{m}{2}$,那麽我們就需要用額外的本不需要動的數字來填充其中了,討論一下即可
註意還要討論一下第一位數字的值
D(後綴樹)
題意:
給出一個字符串S,一個整數l,一個整數k
|S|<=2e5,l<=2e5,0<=k<=1e12
我們需要求出一共有多少個長度不超過l的字符串T滿足條件,答案可能很大,對1e9+7取模
要滿足的條件是以下程序段跑出的tot的值>=k
分析:
考慮一個簡單的問題,給定了一個字符串T,我們要如何快速統計出tot的值
tot的計算過程實際上是把S的每個後綴當作一個字符串,然後讓T和每個字符串去求一個LCP,然後把所有LCP相加
很自然的想到把S的每個後綴全部加到一個Trie樹中
那麽我們定義一個點的value是它在Trie樹的子樹中單詞節點的個數,那麽我們只需要讓T在Trie樹上走,把經過點的value都加起來就是答案了,進一步的我們可以對於每個點,求出這個點到root這條鏈上的所有value的和,那麽答案就是分叉點處的Σvalue
這明顯可以用後綴樹優化,所以復雜度是O(n)的
好現在我們再來考慮如何統計數目,統計數目也是很簡單的,我們只需要枚舉分叉點的位置,然後後面的那些位任意取(當然第一個自由元並不是26種),累加即可
我們為了優化復雜度,把這個計算過程搬到後綴樹上即可,中間的計算需要在紙上算算,本質上是算等比數列求和
建後綴樹的話,只需要建出逆序的SAM,然後按照slink建樹就行了
時間復雜度O(n)
E(dp)
題意:
給出n,m,p
給出n個m維向量,向量的每一位都是0/1
問有多少個集合S,其中異或運算在S中是封閉的,且T∈S
答案對p取模
1<=n<=100,1<=m<=min(2000,2^n),1<=p<=1e9
分析:
S實際上就是包含T的線性子空間,所以就是求秩為m-rank(T)的線性子空間的個數
我們考慮生成線性子空間的線性基的過程,從高位到低位放線性基
每次我們有兩種決策,那就是在當前列的主元位置放一個1(上面行的對應列都必須是0),或者當前位置放置0,之前有元素的行的對應位置可以隨便填0/1
於是我們就有了dp式子,dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*2^j
dp[i][j]表示填了i列填了j個主元的方案數
F(記憶化搜索+論文剪枝)
待填坑
G(貪心)
題意:
給出一個1~n的排列,你可以把它分割成最多k段並且可以把這k個段進行排序,輸出你能得到的最小字典序。
n<=1e5
分析:
貪心著來,先把1砍出來,然後把2砍出來……
這樣可能會面臨剩下最後一刀,但是不能把下一個數字砍出來了(因為可能需要兩刀),去討論最後一刀的情況就行了
H(標記回收線段樹)
題意:
給出一個長度為n的數組a[],有q個操作,操作有兩種
1 l r v :把a[l..r]全部改成數字v
2 :撤銷目前存在的最早的1操作
對於每次操作之後,你需要計算數組的數字和,並把它累加起來最後輸出
n,q,v<=1e5
分析:
有了2操作,很容易想到是可持久化線段樹,但是仔細一想,區間覆蓋操作是不支持減法的,所以可持久化線段樹好像無法做
我們可以考慮這樣來做,第i次1操作就把對應區間的值改成i,然後刪除一個操作i就是把數組裏所有數字i刪除,變成初始狀態
因為是按照操作順序刪除操作的,所以這樣是正確的
我們只需要考慮用線段樹來維護這個過程就行了
我們假設剛開始每個位置染的顏色是inf(表示沒有被染,是原來的值)
我們現在線段樹要處理問題的核心是“將數組中所有顏色i全部刪除,變成inf,維護區間和”
我們可以維護一下區間顏色min,如果一個區間顏色min>i,那麽就不需要進去改顏色了(因為改顏色的過程是遞增的)
這樣每次刪除的話時間復雜度是O(顏色段數),這樣可行嗎?
我們可以來分析一下,剛開始加入一個顏色區間,該顏色區間有log段,然後以後在染色的過程中,最多把之前的一個顏色分成兩部分,所以一次修改操作只會讓總段數多出log段,整體時間復雜度還是在O(nlogn)量級的
有一點需要註意,在刪除一個區間的標記之後,我們還需要將它子樹裏的標記全部清空(或者在做修改操作時候清空子樹標記也是可行的),所以我們的線段樹還需要標記回收,這也是不影響復雜度的
I
待填坑
J
待填坑
K(不平等博弈)
題意:
在一個n個點的樹上,Alice和Bob要進行博弈,首先Alice在任意一個地方下一個白棋,然後Bob在一個白棋的周圍下個黑棋,然後Alice在一個白棋的周圍下一個白棋……誰不能操作就算輸
n<=100
分析:
這是個不平等博弈,所以考慮用dp解決
dp[i]表示在以i為根的子樹上下棋,Alice先手在根下,最終Alice會比Bob多走多少步
那麽在i的k個分叉中,Bob會先選擇一個dp[u]最大的一個下黑棋,不讓Alice下白棋,然後Alice會選擇dp[u]第二大的點下白棋,然後Bob會選擇一個dp[u]第三大的點下黑棋……
那麽把dp[u]排序後,我們去累加一下求和就能得到dp[i]的值了
註意一點,最後dp[i]=max(dp[i],0),即如果走這個子樹Alice比Bob走的少,那麽Alice不會選擇走這個子樹
最後看一下dp[1]的值和0的大小關系就知道是Alice贏還是Bob贏了
時間復雜度是O(nlogn)的
寒武紀camp Day4