51nod 1129 字符串最大值
首先我们可以想到的是,既然求的是前缀的长度,就意味着一定是从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 }
象脑洞理解一下就好,我口胡的不清楚=-=