題意中文題不說了。
做法:字尾陣列,想把兩個串連線起來,求sa和height陣列,因為題目要求求的公共子串,而且每乙個串只出現一次,所以標記每乙個字尾屬於哪乙個串,遍歷heigh陣列,然後判斷周圍有沒有height值大於等於當前下標的,如果沒有則這個串的是可以取得,
但不過,直接去這個串是不行的,所以應該是 max(height[i-1],height[i+1])+1這樣才能取到最小值。
上決╇ф大佬的做法就不怎麼看的懂了
•將兩個串用
#連線,求字尾陣列以及
height陣列
•列舉每乙個
字首 ,
維護這個往前和往後第乙個和這個字首的起點不在同乙個串中的位置,以及第乙個和這個字首的起點在同乙個串中的位置。 •
定義乙個函式f(i
),為字尾
i的乙個最短字首,滿足這個字串只在該串**現了一次,可以往前往後和本串中的字尾求最長公共字首,然後取f(i
)=max(
heigth
)+1
•列舉每乙個字尾i,
他前面第乙個和他不再同乙個串中的字尾
j,他後面第乙個和他不再同乙個串中的字尾
k。求出
ij的最長公共字首長度
x,求出
ik的最長公共前傳
y。根據f(i
),f(j),f(k)
和x,y
來共同確定時候在這個位置有答案。並維護答案的最小值
我覺得上面的有第二個地方應該是字尾,,,只是我覺得啊。。。
#includeusing namespace std;
typedef long long ll;
const int n=2e5+10;
int sa[n],height[n],c[n],x[n],t1[n],t2[n],n,s[n];
int dmin[n][20],rk[n];
void get_sa(int m)
}void get_height()
}void get_height()
int nxt[n][2],pre[n][2];
int super;
int gett(int pos)
int getlen(int pos)
char str1[n],str2[n];
int main()
int ans=n;
for(int i=1;imax_len) continue;
ans=min(ans,min_len);
}if(ans==n) cout<<"-1"
}
Trie上的字尾陣列
亦稱為廣義字尾陣列 lcs longest common suffix lcp longest common preffix sv s v表示trie上節點v到根的路徑形成的字串 由於在trie上,自帶去重功能 顯然l cs s u,sv de plca u,v lcs su,sv depl ca ...
trie上構建字尾陣列
往事太多,有時候忘了就忘了吧。如果有非記不可的,就只能用點附加手段啦 我們定義一棵往事樹是乙個 n 個點 n 1 條邊的有向無環圖,點編號為 1到 n,其中 1 號點被稱為是根結點,除根結點以外,每個點都恰有一條出邊 即以其作為起點的邊 每條邊上有 1 個字元 這裡我們實際上用乙個不大於 300的非...
trie上構建字尾陣列
往事太多,有時候忘了就忘了吧。如果有非記不可的,就只能用點附加手段啦 我們定義一棵往事樹是乙個 n 個點 n 1 條邊的有向無環圖,點編號為 1到 n,其中 1 號點被稱為是根結點,除根結點以外,每個點都恰有一條出邊 即以其作為起點的邊 每條邊上有 1 個字元 這裡我們實際上用乙個不大於 300的非...