马拉车的模板
void init(){ int k=0; ma[k++] ='$'; for(int i=0;i<n;i++){//n是s的长度 ma[k++]='#'; ma[k++]=s[i]; } ma[k++]='#'; len=k; } int Manacher(){ Len[0]=0; int sum = 0,id=0,mx = 0; for(int i=1;i<len;i++){ if(i < mx) Len[i] = min(mx - i, Len[2 * id - i]); else Len[i] = 1; while(i-Len[i]>0 && i+Len[i]<len && ma[i - Len[i]]== ma[i + Len[i]]){ Len[i]++; } if(Len[i] + i > mx){ mx = Len[i] + i; id = i; sum=max(Len[i],sum); } } return (sum - 1); }
ma[] $ # a # b # a # a #
Len[] 1 2 1 4 1 2 3 2 1
复杂度o(n)
模板题1hdu3068,问最长的回文字符长度
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define il inline 6 #define it register int 7 #define inf 0x3f3f3f3f 8 #define lowbit(x) (x)&(-x) 9 #define pii pair<int,int> 10 #define mak(n,m) make_pair(n,m) 11 #define mem(a,b) memset(a,b,sizeof(a)) 12 #define mod 998244353 13 #define fi first 14 #define se second 15 #define sz(x) (int)(x).size() 16 #define all(x) (x).begin(), (x).end() 17 const int maxn=1e6+10; 18 int t; 19 char s[maxn]; 20 char ma[maxn*2]; 21 int Len[maxn*2],len,pos; 22 void init(int l){ 23 int k=0; 24 ma[k++] = '$'; 25 for(int i=0;i<l;i++){ 26 ma[k++]='#'; 27 ma[k++]=s[i]; 28 } 29 ma[k++]='#'; 30 len=k; 31 } 32 33 int Manacher(){ 34 Len[0]=0; 35 int sum = 0,id=0,mx = 0; 36 for(int i=1;i<len;i++){ 37 if(i < mx) Len[i] = min(mx - i, Len[2 * id - i]); 38 else Len[i] = 1; 39 while(i-Len[i]>0 && i+Len[i]<len && ma[i - Len[i]]== ma[i + Len[i]]) Len[i]++; 40 if(Len[i] + i > mx){ 41 mx = Len[i] + i; 42 id = i; 43 sum=max(Len[i],sum); 44 } 45 } 46 return (sum - 1); 47 } 48 int main() { 49 while(~scanf("%s",s)){ 50 init(strlen(s)); 51 printf("%d\n",Manacher()); 52 } 53 return 0; 54 }
模板题2hdu4513 ,问一排身高的人,有多少是凸起回文身高
比如2 3 2算3 但2 1 2算1
其实就是里面将ma[i-Len[i]+2]>=ma[i-Len[i]]的条件。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define il inline 6 #define it register int 7 #define inf 0x3f3f3f3f 8 #define lowbit(x) (x)&(-x) 9 #define pii pair<int,int> 10 #define mak(n,m) make_pair(n,m) 11 #define mem(a,b) memset(a,b,sizeof(a)) 12 #define mod 998244353 13 #define fi first 14 #define se second 15 #define sz(x) (int)(x).size() 16 #define all(x) (x).begin(), (x).end() 17 const int maxn=1e5+10; 18 int t,n; 19 int s[maxn]; 20 int ma[maxn*2]; 21 int Len[maxn*2],len,pos; 22 void init(){ 23 int k=0; 24 ma[k++] = -2; 25 for(int i=0;i<n;i++){ 26 ma[k++]=-1; 27 ma[k++]=s[i]; 28 } 29 ma[k++]=-1; 30 len=k; 31 } 32 33 int Manacher(){ 34 Len[0]=0; 35 int sum = 0,id=0,mx = 0; 36 for(int i=1;i<len;i++){ 37 if(i < mx) Len[i] = min(mx - i, Len[2 * id - i]); 38 else Len[i] = 1; 39 while(i-Len[i]>0 && i+Len[i]<len && ma[i - Len[i]]== ma[i + Len[i]] && ma[i-Len[i]+2]>=ma[i-Len[i]]){ 40 Len[i]++; 41 } 42 if(Len[i] + i > mx){ 43 mx = Len[i] + i; 44 id = i; 45 sum=max(Len[i],sum); 46 } 47 } 48 return (sum - 1); 49 } 50 int main() { 51 scanf("%d",&t); 52 while(t--){ 53 scanf("%d",&n); 54 for(it i=0;i<n;i++){ 55 scanf("%d",&s[i]); 56 } 57 init(); 58 printf("%d\n",Manacher()); 59 } 60 return 0; 61 }
Codeforces Global Round 7 D题
题意:
给t个字符串s,题意好难说啊,
样例输入 输出
5
a a
abcdfdcecba abcdfdcba
abbaxyzyx xyzyx
codeforces c或者s
accbbca acbbca
就是求s的前缀,和s的后缀组成最长的回文子串,输出它
样例二s的前缀abcdfd和s的后缀cba可以组成abcdfdcba
思路:
如果头和尾是相等,往里找,头和尾不相等的,比如第五个样例accbbca,ac是相等的所以只要cbb里找两头最长的回文字符串,直接马拉车
找位置的时候需要条件要符合i-Len[i]==0 or i+Len[i]==len(模拟赛的时候这个条件没看到直接裂开了,而且本来的马拉车模板是错的)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define il inline 6 #define it register int 7 #define inf 0x3f3f3f3f 8 #define lowbit(x) (x)&(-x) 9 #define pii pair<int,int> 10 #define mak(n,m) make_pair(n,m) 11 #define mem(a,b) memset(a,b,sizeof(a)) 12 #define mod 998244353 13 #define fi first 14 #define se second 15 #define sz(x) (int)(x).size() 16 #define all(x) (x).begin(), (x).end() 17 const int maxn=1e6+10; 18 int t; 19 char s[maxn],ss[maxn]; 20 char ma[maxn*2]; 21 int Len[maxn*2],cc,pos; 22 void init(int l,int r){ 23 int k=0; 24 ma[k++] = '$'; 25 for(int i=l;i<=r;i++){ 26 ma[k++]='#'; 27 ma[k++]=s[i]; 28 } 29 ma[k++]='#'; 30 cc=k; 31 } 32 33 int Manacher(){ 34 Len[0]=0; 35 int sum = 0,id=0,mx = 0; 36 pos=0; 37 for(int i=1;i<cc;i++){ 38 if(i < mx) Len[i] = min(mx - i, Len[2 * id - i]); 39 else Len[i] = 1; 40 while(i-Len[i]>0 && i+Len[i]<cc && ma[i - Len[i]]== ma[i + Len[i]]) Len[i]++; 41 if(Len[i] + i > mx){ 42 mx = Len[i] + i; 43 id = i; 44 if(Len[i]>sum &&( i-Len[i]==0 || i+Len[i]==cc)){ 45 sum=Len[i];pos=i; 46 } 47 } 48 } 49 return (sum - 1); 50 } 51 int main() { 52 scanf("%d",&t); 53 while(t--){ 54 scanf("%s",s); 55 int ls=strlen(s); 56 int l=0,r=ls-1; 57 while(s[l]==s[r] && l<=r){ 58 ss[l]=s[l];l++;r--; 59 } 60 if(l>r){ 61 printf("%s\n",s);continue; 62 } 63 init(l,r); 64 int chang=Manacher(); 65 for(it i=0;i<l;i++){ 66 printf("%c",ss[i]); 67 } 68 for(it i=pos-chang+1;i<=pos+chang-1;i+=2){ 69 printf("%c",ma[i]); 70 } 71 for(it i=l-1;i>=0;i--){ 72 printf("%c",ss[i]); 73 } 74 printf("\n"); 75 } 76 return 0; 77 }
坚持自己所热爱的就是最好的