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]<<'\n';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('\n');
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 }
来源:https://www.cnblogs.com/wangzhebufangqi/p/11523771.html
