回文相关算法

Manacher

AC BZOJ 2565

  1 #include <cstdio>
  2 #include <fstream>
  3 #include <iostream>
  4  
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <algorithm>
  8 #include <cmath>
  9  
 10 #include <queue>
 11 #include <vector>
 12 #include <map>
 13 #include <set>
 14 #include <stack>
 15 #include <list>
 16  
 17 typedef unsigned int uint;
 18 typedef long long int ll;
 19 typedef unsigned long long int ull;
 20 typedef double db;
 21  
 22 using namespace std;
 23  
 24 inline int getint()
 25 {
 26     int res=0;
 27     char c=getchar();
 28     bool mi=false;
 29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 31     return mi ? -res : res;
 32 }
 33 inline ll getll()
 34 {
 35     ll res=0;
 36     char c=getchar();
 37     bool mi=false;
 38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 40     return mi ? -res : res;
 41 }
 42 
 43 //==============================================================================
 44 //==============================================================================
 45 //==============================================================================
 46 //==============================================================================
 47 
 48 int n,len;
 49 
 50 char s[205000];
 51 char t[405000];
 52 
 53 int l[405000];
 54 int v[205000];
 55 
 56 int a[205000];
 57 int b[205000];
 58 
 59 int main()
 60 {
 61     //read
 62     {
 63         char c;
 64         while(!islower(c=getchar()));
 65         s[n++]=c;
 66         while(islower(c=getchar())) s[n++]=c;
 67     }
 68     
 69     //Manacher
 70     {
 71         for(int i=0;i<n;i++)
 72         t[i*2]='#',t[i*2+1]=s[i];
 73     
 74         len=n*2+1;
 75         t[0]='[';
 76         t[len-1]=']';
 77         
 78         int mx=1,p=0;
 79         for(int i=0;i<len;i++)
 80         {
 81             l[i]=( mx>i ? min(l[2*p-i],mx-i) : 1 );
 82             
 83             while(t[i-l[i]]==t[i+l[i]]) l[i]++;
 84             
 85             if(l[i]+i>mx)
 86             {
 87                 p=i;
 88                 mx=l[i]+i;
 89             }
 90         }
 91     }
 92     
 93     //cal
 94     int p=0;
 95     for(int i=0;i<len;i++)
 96     {
 97         while(p+l[p]<=i) p++;
 98         a[i]=i-p+1;
 99     }
100     
101     p=len-1;
102     for(int i=len-1;i>=0;i--)
103     {
104         while(p-l[p]>=i) p--;
105         b[i]=p-i+1;
106     }
107     
108     int res=0;
109     for(int i=2;i<len-2;i+=2)
110     res=max(res,a[i-1]+b[i+1]);
111     
112     printf("%d
",res);
113 
114     return 0;
115 }
View Code

代码很短很好背也比较容易理解....

注意一下细节,比如min还有加一减一之类还有大于和不小于之类就差不多了......

原文地址:https://www.cnblogs.com/DragoonKiller/p/4536745.html