1. 程式人生 > >51nod 1129 字符串最大值

51nod 1129 字符串最大值

能夠 define 怎麽 可能 理解 個性 既然 最大值 next

首先我們可以想到的是,既然求的是前綴的長度,就意味著一定是從1開始的,那麽我們可以直接用下
標表示每一個前綴。
但是可能存在幾個前綴互相包含的情況,比如:
abababa
我們可以看見的是
aba中包含著ab和a
abab中包含著aba, ab和a
從上面我們能觀察出一個性質來:
將原字符串自匹配後,掃描到字符i時,next[i]存的是他的一個最近的子前綴結尾點
我們想為什麽會這樣呢?加入某個結尾為i的前綴
包含著結尾為j的前綴,那麽就說明,由前綴j在擴展時擴展失敗了,那麽next[i]就等於j
這樣我們就能夠快速把出現次數累加下去,不過這就意味著我們最後要倒著統計,由較長的前綴逐步累
加到較短前綴上。
怎麽說呢,抽

技術分享圖片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int maxn = 1000086;
 5 char ch[maxn];
 6 ll n, next_[maxn];
 7 ll cnt[maxn];
 8 
 9 int main() {
10     cin >> ch + 1;
11     n = strlen(ch + 1);
12     next_[1] = 0;
13     for(int i = 2, j = 0; i <= n; ++i) {
14 while(j > 0 && ch[i] != ch[j + 1]) j = next_[j]; 15 if(ch[i] == ch[j + 1]) j++; 16 next_[i] = j; 17 } 18 for(int i = n; i >= 1; --i) { 19 cnt[i] += 1; 20 cnt[next_[i]] += cnt[i]; 21 } 22 ll ans = -1000; 23 for(int i = 1; i <= n; ++i)
24 ans = max(ans, cnt[i] * i); 25 cout << ans << \n; 26 return 0; 27 }
View Code

象腦洞理解一下就好,我口胡的不清楚=-=

51nod 1129 字符串最大值