OKR-Periods of Words
题目链接:https://ac.nowcoder.com/acm/contest/955/D
思路: 要求的是最大循环节 那么就是用i-最小的公共前后缀来得到
暴力的话就是 每次i的时候nxt[i] 都往回跳直到不能跳为止,但这样最坏可能会到n^2
考虑如何优化 每次前面跳的时候直接让 nxt[i] 变化到最小 那么后面跳的时候就不会跳冗余的路径
相当于每个点只跳一次
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define ull unsigned long long 7 #define pi pair<int,int> 8 #define fi first 9 #define sc second 10 #define pb push_back 11 12 13 char s[maxn]; 14 int nxt[maxn]; 15 16 17 int main() 18 { 19 ios::sync_with_stdio(false); 20 cin.tie(0); 21 int n; 22 cin>>n>>(s+1); 23 for(int i=2,j=0;i<=n;i++) 24 { 25 while(j&&s[i]!=s[j+1]) j=nxt[j]; 26 if(s[i]==s[j+1]) j++; 27 nxt[i]=j; 28 } 29 ll ans=0; 30 for(int i=1;i<=n;i++) 31 { 32 while(nxt[nxt[i]]) nxt[i]=nxt[nxt[i]]; 33 if(nxt[i]) ans+=i-nxt[i]; 34 } 35 cout<<ans<<'\n'; 36 37 }

浙公网安备 33010602011771号