Manacher基础学习

马拉车的模板

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

模板题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 }
View Code

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

坚持自己所热爱的就是最好的

猜你喜欢

转载自www.cnblogs.com/luoyugongxi/p/12534565.html