马拉车maracher
作者:互联网
目的:线性查找一个串的最长回文子串
时间复杂度:O(n)
len[i]表示以i为中心的回文串的半径
2019徐州G colorful string,求所有回文子串的value之和,一个串的value为串中字母种类,dfs预处理了第i位前一个a-z的位置,复杂度26*n
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+100; int t,len[maxn*2]; char S[maxn*2],T[maxn*2],s[maxn*2]; int init(char *str){ int n=strlen(str); for(int i=1,j=0;i<=2*n;j++,i+=2){ s[i]='#'; s[i+1]=str[j]; } s[0]='$'; s[2*n+1]='#'; s[2*n+2]='@'; s[2*n+3]='\n'; return 2*n+1; } void manacher(int n) { int mx=0,p=0; for(int i=1;i<=n;i++){ if(mx>i) len[i]=min(mx-i,len[2*p-i]); else len[i]=1; while(s[i-len[i]]==s[i+len[i]]) len[i]++; if(len[i]+i>mx) mx=len[i]+i,p=i; } } int dp[maxn*2][30],place[30]; int main() { scanf("%s",S); int Len=strlen(S),n=init(S); for(int i=0;i<=n;i++)len[i]=0; manacher(n); ll ans=0; int k=0; for(int i=0;i<26;i++)place[i]=-1000000; for(int i=1;i<=n;i++) { if(i%2==0)place[S[k++]-'a']=i; for(int j=0;j<26;j++)dp[i][j]=place[j]; } for(int i=1;i<=n;i++) { for(int j=0;j<26;j++) { if(i-dp[i][j]<len[i]) { ans+=1ll*(len[i]-(i-dp[i][j]))/2; } } } printf("%lld\n",ans); return 0; }View Code
标签:int,复杂度,maracher,len,maxn,回文,mx,拉车 来源: https://www.cnblogs.com/myrtle/p/11492707.html