[kuangbin专题] Manacher

时间:2019-09-15
本文章向大家介绍[kuangbin专题] Manacher,主要包括[kuangbin专题] Manacher使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

https://vjudge.net/contest/284138#overview

A、Palindrome

最长回文子串,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 }
View Code

B、吉哥系列故事——完美队形II

最长非递减回文子串,在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 }
View Code

C - Girls' research

最长回文子串,需要记录子串下标

用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 }
View Code

D - Making Huge Palindromes

在一个串末尾添加尽量少的任意字符使得该串成为回文串。

 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 }
View Code

原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11523771.html