hiho一下121周 字尾陣列二 重複旋律2

2022-09-17 22:09:21 字數 2559 閱讀 2885

時間限制:5000ms

單點時限:1000ms

記憶體限制:256mb

描述小hi平時的一大興趣愛好就是演奏鋼琴。我們知道乙個**旋律被表示為長度為 n 的數構成的數列。小hi在練習過很多曲子以後發現很多作品自身包含一樣的旋律。

旋律可以表示為一段連續的數列,相似的旋律在原數列不可重疊,比如在1 2 3 2 3 2 1 中 2 3 2 出現了一次,2 3 出現了兩次,小hi想知道一段旋律**現次數至少為兩次的旋律最長是多少?

解題方法提示

輸入第一行乙個整數 n。1≤n≤100000

接下來有 n 個整數,表示每個音的數字。1≤數字≤1000

輸出一行乙個整數,表示答案。

樣例輸入

8

1 2 3 2 3 2 3 1

樣例輸出

小ho:這一次的問題該如何解決呢?

小hi:嗯,這次的問題被稱為最長不可重疊重複子串問題。

小ho:和上次的問題好像啊,但是這一次是不可以重疊的,直接使用上次的演算法似乎行不通喔。

小hi:是的。問題的關鍵就出在直接用 height 陣列不能保證兩字尾不重疊,我們得換個思路考慮。

小ho:可不可以二分答案,轉化成判定問題呢?

小hi:是個好思路,這的確是可行的。我們先二分乙個k,表示我們假設串中存在長度為k的不可重疊重複子串。

小ho:嗯,就是這個意思。

小hi:存在長度為k的不可重複子串等價於存在兩個字尾有長度為k的公共字首(這裡沒有要求不重疊)。我們檢查 height 陣列中有哪些值 ≥ k。並且如果有連續的height值 ≥ k,就把對應的字尾分在同一組。這樣就保證了該組中所有字尾兩兩之間的最長公共字首都是不小於k的。

我們以樣例為例,看一下k=2和k=3的情況。xi

height

k=2k=318

01 2 3 2 3 2 3 111

2 3 160

2 3 2 3 142

>=2

2 3 2 3 2 3 124

>=2

>=3

3 17

03 2 3 151

3 2 3 2 3 133

>=2

>=3

可以看出,當k=2時,"231"和"23231"的公共字首大於等於k,"23231"和"2323231"的公共字首也大於等k,所以這3個排名連續的字尾會被分到一組。同理"3231"和"323231"也會被分到一組。

對於k=3,"23231"和"2323231"分到一組,"3131"和"323231"分到一組。

小ho:我知道了!

小hi:對,沒錯!下面我們要看看能不能找出不重疊的重複子串。對於每一組,我們檢查這些字尾對應的sa值(也就是字尾起點在原串中的位置i)。如果max - min >= k,那麼就說明我們能找出一組不重疊的重複子串。

例如對於k=3,"23231"和"2323231"的sa值是4和2,"3131"和"323231"這一組的sa值是5和3,差值都不滿足大於等於3,所以找不出不重疊的。

對於k=2,第一組max-min=6-2=4滿足大於等於2,所以能找出不重疊的。

我們給出如下c++**:

bool check(int k)

else

return false;

}

小ho:哈哈,不難嘛,我馬上去實現一發!

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 2e9

#define met(a,b) memset(a,b,sizeof a)typedef

long

long

ll;using

namespace

std;

const

int n = 2e5+5

;const

int m = 4e5+5

;int cmp(int *r,int a,int b,int

l) int

wa[n],wb[n],wss[n],wv[n];

int rank[n];//

字尾i在sa中的排名

int height[n];//

sa[i]與sa[i-1]的lcp

int sa[n];//

sa[i]表示排名第i小的字尾的下標

void da(int *r, int *sa, int n, int m)

}void calheight(int *r,int n)

intn,m;

intaa[n];

int maxx=1,minn=1

;bool solve(int

k)

else

}return

false;}

intmain ()

printf(

"%d\n

",ans);

return0;

}

hiho一下 第二週

題目名稱 trie樹 小hi和小ho是一對好朋友,出生在資訊化社會的他們對程式設計產生了莫大的興趣,他們約定好互相幫助,在程式設計的學習道路上一同前進。這一天,他們遇到了一本詞典,於是小hi就向小ho提出了那個經典的問題 小ho,你能不能對於每乙個我給出的字串,都在這個詞典裡面找到以這個字串開頭的所...

hiho一下 第128周 字尾自動機

求給定字串s不同子串的個數 即求該字串構成的字尾自動機裡面包含了多少個字尾 等價於求這個字尾自動機裡面的路徑的個數 每個字尾自動機節點所包含的字尾集合大小為len p len link p 其中len為該節點到根的長度,link為該節點的字尾鏈結 求和輸出即可 include include inc...

hiho一下第二週 Trie樹

小hi和小ho是一對好朋友,出生在資訊化社會的他們對程式設計產生了莫大的興趣,他們約定好互相幫助,在程式設計的學習道路上一同前進。這一天,他們遇到了一本詞典,於是小hi就向小ho提出了那個經典的問題 小ho,你能不能對於每乙個我給出的字串,都在這個詞典裡面找到以這個字串開頭的所有單詞呢?身經百戰的小...