https://vjudge.net/contest/284138#overview
最长回文子串,Manacher模板题
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 char str[MAXN],nstr[MAXN<<1]; 29 int r[MAXN<<1]; 30 int len; 31 int read() 32 { 33 int s=1,x=0; 34 char ch=getchar(); 35 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 36 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 37 return x*s; 38 } 39 int Manacher() 40 { 41 for(int i=1;i<=len;++i) nstr[2*i-1]='%',nstr[2*i]=str[i]; 42 nstr[len=2*len+1]='%'; 43 int pos=0,R=0; 44 for(int i=1;i<=len;++i) 45 { 46 if(i<R) r[i]=min(r[2*pos-i],R-i); 47 else r[i]=1; 48 while(i-r[i]>=1&&i+r[i]<=len&&nstr[i-r[i]]==nstr[i+r[i]]) r[i]++; 49 if(i+r[i]>R) pos=i,R=i+r[i]; 50 } 51 int res=0; 52 for(int i=1;i<=len;++i) res=max(res,r[i]-1); 53 return res; 54 } 55 int main() 56 { 57 ios::sync_with_stdio(false); 58 cin.tie(0);cout.tie(0); 59 int cnt=0; 60 while(true) 61 { 62 cin>>str+1; 63 len=strlen(str+1); 64 if(str[1]=='E') return 0; 65 cout<<"Case "<<++cnt<<": "<<Manacher()<<endl; 66 } 67 }
最长非递减回文子串,在Manacher基础上修改,增加nstr[i-r[i]]<=nstr[i-r[i]+2]
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 int str[MAXN],nstr[MAXN<<1]; 29 int r[MAXN<<1]; 30 int len; 31 int read() 32 { 33 int s=1,x=0; 34 char ch=getchar(); 35 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 36 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 37 return x*s; 38 } 39 int Manacher() 40 { 41 for(int i=1;i<=len;++i) nstr[2*i-1]=251,nstr[2*i]=str[i]; 42 nstr[len=2*len+1]=251; 43 int pos=0,R=0; 44 for(int i=1;i<=len;++i) 45 { 46 if(i<R) r[i]=min(r[2*pos-i],R-i); 47 else r[i]=1; 48 while(i-r[i]>=1&&i+r[i]<=len&&nstr[i-r[i]]==nstr[i+r[i]] 49 &&nstr[i-r[i]]<=nstr[i-r[i]+2]) r[i]++; 50 if(i+r[i]>R) pos=i,R=i+r[i]; 51 } 52 int res=0; 53 for(int i=1;i<=len;++i) res=max(res,r[i]-1); 54 return res; 55 } 56 int main() 57 { 58 int test=read(); 59 while(test--) 60 { 61 len=read(); 62 for(int i=1;i<=len;++i) 63 str[i]=read(); 64 cout<<Manacher()<<endl; 65 } 66 }
最长回文子串,需要记录子串下标
用Manacher算法时,构造的新字符串奇数位为添加的符号,偶数位是原来的字符。
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 char str[MAXN],nstr[MAXN<<1]; 29 int r[MAXN<<1]; 30 int len; 31 int read() 32 { 33 int s=1,x=0; 34 char ch=getchar(); 35 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 36 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 37 return x*s; 38 } 39 void Manacher() 40 { 41 for(int i=1;i<=len;++i) nstr[2*i-1]='%',nstr[2*i]=str[i]; 42 nstr[len=2*len+1]='%'; 43 int pos=0,R=0; 44 for(int i=1;i<=len;++i) 45 { 46 if(i<R) r[i]=min(r[2*pos-i],R-i); 47 else r[i]=1; 48 while(i-r[i]>=1&&i+r[i]<=len&&nstr[i-r[i]]==nstr[i+r[i]]) r[i]++; 49 if(i+r[i]>R) pos=i,R=i+r[i]; 50 } 51 int po=0,ma=0; 52 // for(int i=1;i<=len;++i) cout<<"i: "<<i<<" r[i]: "<<r[i]<<' ';cout<<endl; 53 for(int i=1;i<=len;++i) 54 if(r[i]>ma) 55 { 56 ma=r[i]; 57 po=i; 58 } 59 if(ma-1<2) 60 { 61 puts("No solution!"); 62 return ; 63 } 64 // cout<<po<<' '<<ma<<endl; 65 int num=ma/2-!(po%2);//两侧回文字符个数,不含中间字符 66 int l=po/2-num+po%2; 67 int r=po/2+num; 68 cout<<l-1<<' '<<r-1<<endl; 69 for(int i=l;i<=r;++i) 70 putchar(str[i]); 71 putchar(' '); 72 73 } 74 //a qqqzuiiuzaaaa 75 int main() 76 { 77 char ch; 78 while(scanf("%c",&ch)!=EOF) 79 { 80 scanf("%s",str+1);getchar(); 81 len=strlen(str+1); 82 int del=ch-'a'; 83 for(int i=1;i<=len;++i) 84 if(str[i]-del<'a') str[i]=str[i]-del+26; 85 else str[i]-=del; 86 Manacher(); 87 } 88 return 0; 89 }
在一个串末尾添加尽量少的任意字符使得该串成为回文串。
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define lowbit(x) (x&(-x)) 26 using namespace std; 27 const int MAXN=1e6+5; 28 char str[MAXN],nstr[MAXN<<1]; 29 int r[MAXN<<1]; 30 int len; 31 int read() 32 { 33 int s=1,x=0; 34 char ch=getchar(); 35 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 36 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 37 return x*s; 38 } 39 int Manacher() 40 { 41 for(int i=1;i<=len;++i) nstr[2*i-1]='%',nstr[2*i]=str[i]; 42 nstr[len=2*len+1]='%'; 43 int pos=0,R=0; 44 for(int i=1;i<=len;++i) 45 { 46 if(i<R) r[i]=min(r[2*pos-i],R-i); 47 else r[i]=1; 48 while(i-r[i]>=1&&i+r[i]<=len&& 49 nstr[i-r[i]]==nstr[i+r[i]]) r[i]++; 50 if(i+r[i]>R) pos=i,R=i+r[i]; 51 } 52 int res=len; 53 for(int i=1;i<=len;++i) 54 { 55 if(i+r[i]-1==len) 56 res=min(res,(len-(2*r[i]-1))/2); 57 } 58 return res; 59 } 60 int main() 61 { 62 // ios::sync_with_stdio(false); 63 // cin.tie(0);cout.tie(0); 64 int test=read(); 65 for(int pp=1;pp<=test;++pp) 66 { 67 cout<<"Case "<<pp<<": "; 68 cin>>str+1; 69 len=strlen(str+1); 70 cout<<Manacher()+strlen(str+1)<<endl; 71 } 72 }