[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题解

A

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <map>
using namespace std;
const int MAX_N = 1000024;
int mo[MAX_N],str[MAX_N];
int Next[MAX_N];
int n2,n1;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||str[i]==str[j]) {++i,++j,Next[i] = j;}
    else j = Next[j];
   }
   return;
}
int kmp(){
   int i = 0,j = 0;
   while(i<n1){
    if(j==-1||mo[i]==str[j]) i++,j++;
    else j = Next[j];
    if(j==n2) return i-n2+1;
   }
   return -1;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(Next,0,sizeof(Next));
        scanf("%d%d",&n1,&n2);
        for(int i = 0;i<n1;i++){
            i==(n1-1)?scanf("%d",&mo[i]):scanf("%d",&mo[i]);
           // printf("%d",mo[i]);
        }
        mo[n1] = '\0';
        //getchar();
        //printf("%s\n",mo);
        for(int i = 0;i<n2;i++){
            i==(n2-1)?scanf("%d",&str[i]):scanf("%d",&str[i]);
            //printf("%d",str[i]);
        }
        str[n2] = '\0';
        //printf("%s\n",str);
        Next[0] = -1;
        getnext();
        printf("%d\n",kmp());

    }
    return 0;
}

B

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 10024;
char str[1000024];
char mo[MAX_N];
int Next[MAX_N];
int n2,n1;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
    else j = Next[j];
   }
   return;
}
int kmp(){
   int ans = 0;
   int i = 0,j = 0;
   while(i<n1){
    if(j==-1||str[i]==mo[j]) {++i,++j;}
    else j = Next[j];
    if(j==n2) ans++;
   }
   return ans;
}
int main(){
   int t;
   scanf("%d",&t);
   while(t--){
    memset(Next,0,sizeof(Next));
    scanf("%s",mo);
    scanf("%s",str);
    n1 = strlen(str);
    n2 = strlen(mo);
    Next[0] = -1;
    getnext();
    printf("%d\n",kmp());
   }
   return 0;
}

C

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N  = 100024;
int Next[MAX_N];
int n1,n2;
char mo[MAX_N],str[MAX_N];
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]){++i,++j,Next[i] = j;}
    else j = Next[j];
   }
   return ;
}
int kmp(){
   int ans = 0,i = 0,j = 0;
   while(i<n1){
    if(j==-1||str[i]==mo[j]) {++i,++j;}
    else j = Next[j];
    if(j==n2)
    {
        j = 0;
        ans++;
    }
   }
   return ans;
}
int main(){
   while(scanf("%s",str)){
    if(str[0]=='#') break;
    memset(Next,0,sizeof(Next));
    scanf("%s",mo);
    n1 = strlen(str);
    n2 = strlen(mo);
    Next[0] = -1;
    getnext();
    printf("%d\n",kmp());
   }
   return 0;
}

D

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int MAX_N = 100024;
int Next[MAX_N];
char mo[MAX_N];
int n2;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]){++i,++j,Next[i]=j;}
    else j = Next[j];
   }
   return;
}
int main(){
   int t;
   scanf("%d",&t);
   while(t--){
    memset(Next,0,sizeof(Next));
    scanf("%s",mo);
    n2 = strlen(mo);
    Next[0] = -1;
    getnext();
    if(n2-Next[n2]==1||(n2%(n2-Next[n2])==0&&n2/(n2-Next[n2])!=1)) printf("0\n");
    else if(n2/(n2-Next[n2])==1&&n2%(n2-Next[n2])==0) printf("%d\n",n2-Next[n2]);
    else printf("%d\n",n2-Next[n2]-n2%(n2-Next[n2]));
   }
   return 0;
}

E

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 1000024;
int Next[MAX_N];
char mo[MAX_N];
int n2;
void getnext(){
   int i = 0,j=-1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]){++i,++j,Next[i]=j;}
    else j =Next[j];
   }
   return ;
}
int main(){
    int cnt = 0;
   while(scanf("%d",&n2)&&n2){
    memset(Next,0,sizeof(Next));
    scanf("%s",mo);
    printf("%Test case #%d\n",++cnt);
    Next[0] = -1;
    getnext();
    for(int i =0;i<n2;++i){
           // dbg(i+1);
            //dbg(i+1-Next[i+1]);
        if(((i+1)%(i+1-Next[i+1]))==0&&((i+1)/(i+1-Next[i+1])!=1)) {
            printf("%d %d\n",i+1,(i+1)/(i+1-Next[i+1]));
        }
    }
    printf("\n");
   }
   return 0;
}

F

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 1000024;
int Next[MAX_N];
char mo[MAX_N];
int n2;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
    else j = Next[j];
   }
   return ;
}
int main(){
   while(scanf("%s",mo)){
    if(mo[0]=='.') break;
    memset(Next,0,sizeof(Next));
    n2 = strlen(mo);
    Next[0] = -1;
    getnext();
    if(n2%(n2-Next[n2])==0) printf("%d\n",n2/(n2-Next[n2]));
    else printf("1\n");
   }
   return 0;
}

G

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 400024;
int Next[MAX_N],ans[MAX_N];
char mo[MAX_N];
int n2;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
    else j=Next[j];
   }
   return ;
}
int main(){
   while(scanf("%s",mo)!=EOF){
    n2 = strlen(mo);
    Next[0] = -1;
    getnext();
    int cnt = 0;
    ans[cnt++] = n2;
    int j = n2;
    while(Next[j]!=0){
        ans[cnt++] = Next[j];
        j = Next[j];
    }
    for(int i = cnt-1;i>=0;i--){
        i==0?printf("%d\n",ans[i]):printf("%d ",ans[i]);
    }
   }
   return 0;
}

H

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
string str[15];
int Next[150];
void getnext(string str){
   Next[0] = -1;
   int n2 = str.length();
   int i = 0,j =-1;
   while(i<n2){
    if(j==-1||str[i]==str[j]){++i,++j,Next[i]=j;}
    else j =Next[j];
   }
   return ;
}
int kmp(string str,string mo){
   int n2 = mo.length();
   int n1 = str.length();
   int i= 0,j=0;
   while(i<n1){
    if(j==-1||str[i]==mo[j]) {++i,++j;}
    else j = Next[j];
    if(j==n2) return 1;
   }
   return 0;
}
int main(){
    ios::sync_with_stdio(false);
   int t;
   cin >> t;
   while(t--){
   int n;
   cin >>n;
   for(int i = 1;i<=n;++i)
    cin >> str[i];
    string str_ans;
    int maxx = 2;
    int flag2 = 0;
   for(int i = 0;i<60;i++){
    for(int j = 1;j<60-i+1;j++){
        int flag = 0;
        string str_now = str[1].substr(i,j);
        getnext(str_now);
        for(int k=1;k<=n;k++){
            if(!kmp(str[k],str_now)) {
                    flag = 1;
                     break;
            }
        }
        if(!flag) if(j>=maxx){
            str_ans = str_now;
            maxx = j;
            flag2 = 1;
        }
    }
   }
   if(flag2)
   cout << str_ans<<endl;
   else cout << "no significant commonalities" << endl;
   }
   return 0;
}

I

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 100024;
int Next[MAX_N],ex[MAX_N];
char str[MAX_N],mo[MAX_N];
void getnext(char *str){
   int i = 0,j,po,len = strlen(str);
   Next[0] = len;
   while(str[i]==str[i+1]&&i+1<len) i++;
   Next[1] = i;
   po = 1;
   for(i = 2;i<len;i++){
    if(Next[i-po]+i<Next[po]+po)
        Next[i] = Next[i-po];
    else {
        j = Next[po] + po - i;
        if(j<0) j = 0;
        while(i+j<len&&str[j]==str[j+i])
            j++;
        Next[i] = j;
        po = i;
    }
   }
}
void exkmp(char *s1,char *s2){
   int i = 0,j ,po ,len = strlen(s1),l2 = strlen(s2);
   getnext(s2);
   while(s1[i]==s2[i]&&i<l2&&i<len) i++;
   ex[0] = i;
   po = 0;
   for(i = 1;i<len;++i){
    if(Next[i-po]+i<ex[po]+po)
     ex[i] = Next[i-po];
     else {
        j = ex[po]+po - i;
        if(j<0) j = 0;
        while(i+j<len&&j<l2&&s1[i+j]==s2[j]) j++;
        ex[i] = j;
        po = i;
     }
   }
}
int main(){
   while(scanf("%s",mo)!=EOF){
    scanf("%s",str);
    exkmp(str,mo);
    int n1 = strlen(str);
    int n2 = strlen(mo);
    int maxx = 0;
    for(int i=0;i<n1;i++){
        //printf("%d\n",ex[i]);
        //printf("%d\n",ex[i]);
            if(ex[i]==n1-i){
            maxx = max(ex[i],maxx);
            }
    }
    if(!maxx) {
            printf("0\n");
             continue;
    }
    else {
     for(int i = 0;i<maxx;i++)
     i==maxx-1?printf("%c ",mo[i]):printf("%c",mo[i]);
    printf("%d\n",maxx);
    }
   }
   return 0;
}

J

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 200024;
int Next[MAX_N],ex[MAX_N];
char str[MAX_N],mo[MAX_N];
void getnext(char *str){
   int i = 0,j,po,len = strlen(str);
   Next[0] = len;
   while(str[i]==str[i+1]&&i+1<len) i++;
   Next[1] = i;
   po = 1;
   for(i = 2;i<len;i++){
    if(Next[i-po]+i<Next[po]+po)
        Next[i] = Next[i-po];
    else {
        j = Next[po] + po - i;
        if(j<0) j = 0;
        while(i+j<len&&str[j]==str[j+i])
            j++;
        Next[i] = j;
        po = i;
    }
   }
}
void exkmp(char *s1,char *s2){
   int i = 0,j ,po ,len = strlen(s1),l2 = strlen(s2);
   getnext(s2);
   while(s1[i]==s2[i]&&i<l2&&i<len) i++;
   ex[0] = i;
   po = 0;
   for(i = 1;i<len;++i){
    if(Next[i-po]+i<ex[po]+po)
     ex[i] = Next[i-po];
     else {
        j = ex[po]+po - i;
        if(j<0) j = 0;
        while(i+j<len&&j<l2&&s1[i+j]==s2[j]) j++;
        ex[i] = j;
        po = i;
     }
   }
}
int main(){
   int t ;
   scanf("%d",&t);
   while(t--){
    int n;
    scanf("%d",&n);
    scanf("%s",mo);
    for(int i = 0;i<n;i++)
        str[i] = mo[i];
    str[n] = '\0';
    exkmp(mo,str);
    int sum = 0;
    for(int i = 0;i<n;++i){
        sum+=ex[i];
        sum%=10007;
    }
    printf("%d\n",sum%=10007);

   }
   return 0;
}

K

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
 //#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 100024;
char mo[35],turn_[35];
string turn(string str){
    int len = str.length();
    for(int i = 0;i<len;i++){
        str[i] = turn_[str[i]-'a'];
    }
    return str;
}
int Next[MAX_N],ex[MAX_N];
void getnext(string str){
   int len = str.length();
   Next[0] = len;
   int i= 0,j ,po;
  while(str[i]==str[i+1]&&i+1<len)
    i++;
    Next[1]  = i;
    po = 1;
    for(i = 2;i<len;i++){
        if(Next[i-po]+i<Next[po]+po)
            Next[i] = Next[i-po];
        else {
            j = Next[po]+po - i;
            if(j<0) j = 0;
            while(i+j<len&&str[j]==str[j+i])
                j++;
            Next[i] = j;
            po = i;
        }
    }
}
void exkmp(string str,string mo){
    int len = str.length();
    int l2 = mo.length();
    int i = 0,j ,po;
    getnext(mo);
   while(str[i]==mo[i]&&i<len&&i<l2)
   i++;
   ex[0] = i ;
   po =  0;
   for(i = 1;i<len;++i){
    if(Next[i-po]+i<ex[po]+po)
        ex[i] = Next[i-po];
    else {
        j = ex[po]+po-i;
        if(j<0) j = 0;
        while(i+j<len&&j<l2&&str[j+i]==mo[j])
            j++;
        ex[i] = j;
        po = i;
    }
   }
}
int main(){
   int t;
   cin >> t;

   while(t--){
    //memset(Next,0,sizeof(Next));
    //memset(ex,0,sizeof(ex));
    for(int i = 0;i<26;i++){
        cin >> mo[i];
        turn_[mo[i]-'a'] = 'a'+i;
    }
    string str;
    cin >>str;
    int len = str.length();
    string str_now = turn(str);
    exkmp(str,str_now);
    //dbg(str);
    //dbg(str_now);
    int len_ans = len;
    /*for(int i = 0;i<len;i++)
        dbg(ex[i]);*/
    //dbg(len/2);
    for(int i = 0;i<len;i++){
               //dbg(ex[i]);
               //dbg(len-i);
               if(ex[i]>i) continue;
        if(ex[i]==len-i) {
            len_ans = i;
            break;
        }
    }
    cout << str.substr(0,len_ans) << str_now.substr(0,len_ans) << endl;

   }
   return 0;
}

L

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
//#define dbg(x) cout<<#x<<" = "<< (x)<< endl
string str[124];
string turn_(string str){
   int len = str.length();
   string str_now="";
   for(int i = len-1;i>=0;i--)
      str_now+=str[i];
      //str_now[len] ='\0';
      //dbg(str_now);
   return str_now;
}
const int MAX_N = 100024;
int Next[MAX_N];
void getnext(string str){
   int len = str.length();
   int i = 0,j = -1;
   Next[0]= -1;
   while(i<len){
    if(j==-1||str[i]==str[j]){++i,++j,Next[i] = j;
    }
    else  j = Next[j];
   }
   return ;
}
int kmp(string str,string mo){
    int n1 = str.length();
    int n2 = mo.length();
    int i = 0,j = 0;
    while(i<n1){
        if(j==-1||str[i]==mo[j]){++i,++j;}
        else j = Next[j];
        if(j==n2) return 1;
    }
    return 0;
}
int main(){
   int t;
   cin >> t;
   while(t--){
    //string a = "ABC";
    //dbg(turn_(a));
    int n;
    cin >> n;
    for(int i = 1;i<=n;++i)
        cin >>str[i];
        int len = str[1].length();
    int maxx = 0;
    for(int i = 0;i<len;i++){
        for(int j = 1;j<len-i+1;j++){
            int flag = 0,flag1 = 0,flag2 = 0;
            string str_now = str[1].substr(i,j);
            //dbg(str_now);
            string str_now_ot = turn_(str_now);
           //dbg(str_now);
           //dbg(str_now_ot);
            for(int k = 1;k<=n;++k){
                getnext(str_now);
                if(kmp(str[k],str_now)) flag1 = 1;
                getnext(str_now_ot);
                if(kmp(str[k],str_now_ot)) flag2 = 1;
                if((!flag1)&&(!flag2)) break;
                if(k==n) flag = 1;
                flag1 = flag2 = 0;
            }
            if(flag) {
                    //dbg(j);
                    maxx=max(maxx,j);
            }
        }
    }
    printf("%d\n",maxx);
   }
   return 0;
}

M

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
//#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
string str[4024];
const int MAX_N = 245;
int Next[MAX_N];
void getnext(string str){
  int n2 = str.length();
  Next[0] = -1;
  int i = 0,j = -1;
  while(i<n2){
    if(j==-1||str[i]==str[j]){++i,++j,Next[i]=j;}
    else j = Next[j];
  }
  return ;
}
int kmp(string str,string mo){
   int n1 = str.length(),n2 = mo.length();
   int i = 0,j = 0;
   while(i<n1){
    if(j==-1||str[i]==mo[j]) {++i,++j;}
    else j = Next[j];
    if(j==n2) return 1;
   }
   return 0;
}
int main(){
   int n;
   while(cin >> n&&n){
    for(int i = 1;i<=n;++i)
      cin >> str[i];
    int len = str[1].length();
    int maxx = 0;
    string str_ans;
    int flag1 = 0;
    for(int i = 0;i<len;++i){
        for(int j = 1;j<len-i+1;++j){
            string str_now = str[1].substr(i,j);
           // dbg(str_now);
            getnext(str_now);
            int flag = 0;
            for(int k = 1;k<=n;++k){
                if(!kmp(str[k],str_now)) {
                    flag = 1;
                    break;
                }
            }
            if(!flag)
            {
                if(!flag1) {
                    flag1 = 1;
                    str_ans = str_now;
                }
                if(j>=maxx){
                    if(j==maxx){
                        if(str_ans>str_now)
                        str_ans = str_now;
                    }

                   else  {
                        str_ans = str_now;
                        maxx = j;
                   }
                }
            }
        }
    }
    if(flag1) cout << str_ans << endl;
    else cout << "IDENTITY LOST" << endl;
   }
   return 0;
}

N

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
const int MAX_N = 2000024;
int ex[MAX_N],Next[MAX_N];
char mo[MAX_N],str[MAX_N],str_max[MAX_N],str_min[MAX_N],str_[MAX_N];
int n1,n2;
int getmin(char *str){
   int i = 0,j = 1,k = 0;
   int len =  strlen(str);
   while(j<len&&i<len&&k<len){
    if(str[(i+k)%len]==str[(j+k)%len]){
        k++;
    }
    else {
    if(str[(i+k)%len]>str[(j+k)%len]){
        i = i + k + 1;
    }
    else {
        j = j + k +1;
    }
    if(i==j)
        j++;
    k = 0;
    }
   }
   return i < j? i : j;
}
int getmax(char *str){
   int len = strlen(str);
   for(int i = 0;i<len;++i){
    str[i+len] = str[i];
   }
   int i = 0,j = 1;
   while(i<len&&j<len){
    int k= 0;
    while(str[i+k] == str[j+k]&&k<len) k++;
    if(k==len) break;
    if(str[i+k]<str[j+k]) i = max(i+k+1,j+1);
    else j = max(j+k+1,i+1);
   }
   return min(i,j);
}
void getnext(char *str){
   int i = 0,po,j,len=strlen(str);
   Next[0] = len;
   while(str[i]==str[i+1]&&i+1<len)
    i++;
   Next[1] = i;
   po = 1;
   for(i = 2;i<len;++i){
    if(Next[i-po]+i<Next[po]+po)
        Next[i] = Next[i-po];
    else {
        j= Next[po] + po -i;
        if(j<0) j = 0;
        while(i+j<len&&str[j]==str[j+i])
            j++;
        Next[i] = j;
        po = i;
    }
   }
}
void exkmp(char *s1,char *s2){
   int i = 0,j ,po,len = strlen(s1),l2 = strlen(s2);
   getnext(s2);
   while(s1[i]==s2[i]&&i<len&&i<l2)
    i++;
   ex[0] = i;
   po = 0;
   for(i = 1;i<len;++i){
    if(Next[i-po] + i<ex[po] + po)
        ex[i] = Next[i -po];
    else{
        j = ex[po]+po - i;
        if(j<0) j = 0;
        while(i+j<len&&j<l2&&s1[j+i]==s2[j])
            j++;
        ex[i] = j;
        po = i;
    }
   }
}
int main(){
    while(scanf("%s",str)!=EOF){
        int len = strlen(str);
        int xb = getmin(str) ;
        for(int i = xb;i<=xb+len-1;i++){
            str_min[i-xb] = str[i%len];
        }
        str_min[len] = '\0';
        xb = getmax(str);
        for(int i = xb;i<=xb+len-1;i++){
            str_max[i-xb] = str[i%len];
        }
        str_max[len] = '\0';

        for(int i = len;i<2*len;i++){
            str[i] = str[i-len];
        }
        str[2*len] = '\0';
        n1 = 2*len;
        n2 = len;
        exkmp(str,str_min);
        int ans_min = 0,ans_max = 0,xb_min=0,xb_max=0;
        for(int i = 0;i<len;i++){
            if(ex[i]==len) {
                ans_min++;
                if(!xb_min) xb_min = i +1;
            }
        }
        exkmp(str,str_max);
         for(int i = 0;i<len;i++){
            if(ex[i]==len) {
                ans_max++;
                if(!xb_max) xb_max = i +1;
            }
        }
        printf("%d %d %d %d\n",xb_min,ans_min,xb_max,ans_max);
    }
    return 0;
}


O

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
set < string > st;
string str[10024];
int getmin(string str){
   int i = 0,j = 1,k = 0,len = str.length();
   while(j<len&&i<len&&k<len){
    if(str[(i+k)%len]==str[(j+k)%len]){
        k++;
    }
    else {
        if(str[(i+k)%len]>str[(j+k)%len])
            i = i+k+1;
        else j = j + k + 1;
        if(i==j)
            j++;
        k = 0;
    }
   }
   return i<j?i:j;
}
int main(){
   int n;
   while(cin >> n){
    for(int i = 1;i<=n;++i){
        cin >> str[i];
        string str_ans="";
        int len = str[i].length();
        int xb = getmin(str[i]);
        str_ans+=str[i].substr(xb,len-xb);
        str_ans+=str[i].substr(0,xb);
        //dbg(str_ans);
        st.insert(str_ans);
    }
    printf("%d\n",st.size());
    st.clear();
   }
   return 0;
}

P

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
const int MAX_N = 1000024;
int Next[MAX_N];
char mo[MAX_N];
int ans[MAX_N];
int n2;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i] = j;}
    else j = Next[j];
   }
   return ;
}
int main(){
   int t;
   scanf("%d",&t);
   for(int k = 1;k<=t;k++){
    memset(ans,0,sizeof(ans));
    //memset(Next,0,sizeof(Next));
    int cnt = 0;
    scanf("%s",mo);
    n2 = strlen(mo);
    Next[0] = -1;
    getnext();
    int j = n2;
    //ans[cnt++]=j-Next[j];
    while(Next[j]!=0){
        ans[cnt++] =n2-Next[j];
        j = Next[j];
    }
    ans[cnt++] = n2;
    printf("Case #%d: %d\n",k,cnt);
   for(int i = 0;i<cnt;i++){
    i==cnt-1?printf("%d\n",ans[i]):printf("%d ",ans[i]);
   }
   }
   return 0;
}

Q 毒瘤题 不想做啊

R

#include<cstdio>
#include<cstring>
#include<algorithm>
#include <iostream>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int maxl=1000000;
char to[35];
int te,p[2*maxl+5],sum[maxl<<1+5];
char s[maxl+5],now[2*maxl+5];

void readln() {scanf("%*[^\n]");getchar();}
bool Eoln(char ch) {return ch==10||ch==13||ch==EOF;}
int reads(char *x)
{
    int len=0;char ch=getchar();if (ch==EOF) return EOF;
    s[++len]=ch;while (!Eoln(s[len])) s[++len]=getchar();s[len--]=0;
    return len;
}
long long Manacher(char *s)
{
    int len=strlen(s);
    //dbg(len);
    now[0] = '@';
    for (int i=1;i<=len;i++)
    {
        //dbg(s[i-1]);
        now[2*i-1]='%',now[2*i]=s[i-1];
        //dbg(now[2*i-1]);
        //dbg(now[2*i]);
    }
    now[len=len*2+1]='%';
    now[len+1] = '$';
    now[len+2] = '\0';
    dbg(now);
    int pos=0,R=0;
    for (int i=1;i<=len;i++)
    {
        if (i<R) p[i]=min(p[2*pos-i],R-i); else p[i]=1;
        while (1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]]==now[i+p[i]]) p[i]++;
        if (i+p[i]>R) {pos=i;R=i+p[i];}
        //printf("%d\n",p[i]);
    }
     for(int i = 1;i<=len;i++){
      if(now[i]<='z'&&now[i]>='a') sum[i] = sum[i-1]+to[now[i]-'a'];
      else sum[i] = sum[i-1];
        }
        for(int i = 1;i<=len;i++)
        printf("%d ",p[i]);
    //for(int i = 1;i<=len;++i)
        //dbg(p[i]);
        //dbg(s);
    long long maxx = 0;
    long long ans ;
    //dbg(now);
    for(int i = 1;i<=len/2;i++){
     ans = 0;
     //dbg(p[i]);
     //dbg(i);
     //dbg(2*(i-1)+(len-2*(i-1)+1)/2);
    if(p[i]==i&&2*p[i]-1!=len) ans+= sum[2*(i-1)];
    //dbg(ans);
    //dbg(2*p[2*(i-1)+(len-2*(i-1)+1)/2]-1);
    //dbg(len-2*(i-1));
    if(2*p[2*(i-1)+(len-2*(i-1)+1)/2]-1==len-2*(i-1)&&i!=1) ans += sum[len]-sum[2*(i-1)];
    //dbg(sum[len]);
    //dbg(ans);
    maxx=max(maxx,ans);
      }
      return maxx;
}
int main()
{
    //freopen("Manacher.in","r",stdin);
    //freopen("Manacher.out","w",stdout);
    int t;
    scanf("%d",&t);
    //scanf("%d",&te);readln();
    while (t--) {
            //for(int i= 0;i<26;++i)
            //scanf("%d",&to[i]);
            scanf("%s",s);
      printf("%I64d\n",Manacher(s));
    }
    return 0;
}

S

比较有意思 可以想一下 就是维护一下前回文 和后回文

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
const int MAX_N = 2000005;
long long ans;
int tree[MAX_N][26],ex[MAX_N];
int cnt[MAX_N][2],Next[MAX_N];
int tot;
char A[MAX_N],B[MAX_N],C[MAX_N<<1];
void Insert(char *str,int p){
   int len = strlen(str);
   int root = 0;
   for(int i = 0;i<len;++i){
    int id = str[i] - 'a';
    if(!tree[root][id]) tree[root][id] = ++tot;
    root = tree[root][id];
    if(i<len-1&&ex[i+1]+i+1==len) cnt[root][1]++;
   }
   cnt[root][0]++;
}
long long Find(char *str,int p){
   int len = strlen(str);
   int root = 0;
   for(int i = 0;i<len;++i){
    int id = str[i] - 'a';
    if(!tree[root][id]) return 0;
    root = tree[root][id];
   if(i<len-1&&ex[i+1]+i+1==len) ans+=cnt[root][0];
   }
   //ans+=cnt[root][0];
   //ans+=str_flag2[p][len];
   //ans+=cnt[root][1];
   //dbg(root);
   //dbg(cnt[root][0]);
   //dbg(cnt[root][1]);
   //dbg(ans);
   return cnt[root][0]+cnt[root][1];
}
void getnext(char *str){
   int i = 0,po,j,len = strlen(str);
   Next[0] = len;
   while(str[i]==str[i+1]&&i+1<len)
   i++;
   Next[1] = i;
   po = 1;
   for(i = 2;i<len;++i){
    if(Next[i-po] + i <Next[po] + po)
    Next[i] = Next[i-po];
    else {
        j = Next[po] + po -i;
        if(j<0) j = 0;
        while(i+j<len&&str[j]==str[j+i])
            j++;
        Next[i] = j;
        po = i;
    }
   }
}
void exkmp(char *s1,char *s2){
   int i= 0,j,po,len = strlen(s1),l2 = strlen(s2);
   getnext(s2);
   while(s1[i]==s2[i]&&i<len&&i<l2)
    i++;
   ex[0] = i;
   po = 0;
   for(i = 1;i<len;++i){
    if(Next[i-po] + i <ex[po]+po)
    ex[i] = Next[i-po];
    else {
        j = ex[po]+po -i ;
        if(j<0) j = 0;
        while(i+j<len&&j<l2&&s1[j+i]==s2[j])
            j++;
        ex[i] = j;
        po = i;
      }
    }
}
void init(){
   for(int i = 0 ;i<=tot;++i){
    cnt[i][0] = 0;
    cnt[i][1] = 0;
    for(int j = 0;j<26;j++)
        tree[i][j] = 0;
   }
   tot = 0;
}
int main(){
    int t,cnt = 0;
    scanf("%d",&t);
            init();
            int len;
    for(int i = 1;i<=t;++i){
       scanf("%d",&len);
       scanf("%s",A);
       for(int j = 0;j<len;++j)
        B[j] = A[len-1-j];
              exkmp(A,B);
             // dbg(A);
             // dbg(B);
              Insert(A,i);
       C[cnt++] = '|';
       for(int j = 0;j<len;j++){
        C[cnt++] = A[j];
       }
       C[cnt] = '\0';
    }
    len = cnt - 1;
    ans = 0;
    //dbg(len);
    //dbg(C);
    cnt = 0;
    for(int i = len;i>=0;i--){
       if(C[i]=='|'){
        A[cnt] = '\0';
        //dbg(A);
        //dbg(cnt);
        int len_now = strlen(A);
       for(int i = 0;i<len_now;i++)
        B[i] = A[len_now-1-i];
        B[len_now] = '\0';
        //dbg(A);
        exkmp(A,B);
        //dbg(A);
        //dbg(B);
        ans+=Find(A,i);
       cnt = 0;
       }
       else A[cnt++] = C[i];
    }
    printf("%I64d\n",ans);
   return 0;
}

T

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
using namespace std;
const int MAX_N = 1000024;
int p[MAX_N<<1+5];
char s[MAX_N+5],now[MAX_N<<1+5];
int Manacher(char *s){
   int len = strlen(s);
   for(int i = 1;i<=len;++i) now[2*i-1] = '%',now[2*i] = s[i-1];
   now[len = len*2+1] = '%';
   int pos = 0,R = 0;
   for(int i = 1;i<=len;++i){
    if(i<R) p[i] = min(p[2*pos-i],R-i);
    else p[i] = 1;
    while(1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]] ==now[i+p[i]]) p[i]++;
    if(i+p[i]>R) {pos = i;R= i+p[i];}
   }
   int MAX = 0;
   for(int i = 1;i<=len;++i) MAX = max(MAX,p[i]-1);
   return MAX;
}
int main(){
   int cnt  = 0;
   while(scanf("%s",s)){
    if(s[0]=='E'&&s[1]=='N'&&s[2]=='D'&&s[3]=='\0') break;
    printf("Case %d: ",++cnt);
    printf("%d\n",Manacher(s));
   }
   return 0;
}

U

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
const int MAX_N = 100010;
int Ma[MAX_N<<1],now[MAX_N<<1],p[MAX_N<<1],s[MAX_N<<1];
int Manacher(int *s,int len){
   int l = 0;
   Ma[l++] = 0;
   Ma[l++] = 2;
   for(int i = 0;i<len;i++){
    Ma[l++] = s[i];
    Ma[l++] = 2;
   }
   Ma[l] = 1;
   //for(int i = 0;i<l;i++)
    //printf("%d",Ma[i]);
   //printf("\n");
   int mx = 0,id = 0;
   for(int i = 0;i<l;i++){
    p[i] = mx>i?min(p[2*id-i],mx-i):1;
    while(Ma[i+p[i]]==Ma[i-p[i]]) {
            if(p[i]>=1) {
            if(Ma[i+p[i]]<=Ma[i+p[i]-2])
            p[i]++;
            else break;
            }
            /*else if(p[i]>=2){
                 if(Ma[i+p[i]]<=Ma[i+p[i]-2])
            p[i]++;
            else p[i]++;
            }*/
            else p[i]++;
    }
    if(i+p[i]>mx){
        mx = i+p[i];
        id = i;
    }
   }
   int MAX = 0;
   for(int i = 1;i<l;++i){
    //dbg(p[i]);
    MAX=max(p[i]-1,MAX);
   }
   return MAX;
}
int main(){
   int t;
   scanf("%d",&t);
   while(t--){
    int n;
    scanf("%d",&n);
    for(int i = 0;i<n;++i)
        scanf("%d",&s[i]);
    printf("%d\n",Manacher(s,n));
   }
   return 0;
}

V

#include <cstdio>
#include <iostream>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
//#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 200024;
char to[35];
char s[MAX_N<<1+5],now[MAX_N<<1+5];
int p[MAX_N<<1+5];
void Manacher(char *s){
   int len = strlen(s);
   for(int i = 1;i<=len;i++) now[2*i-1] = '%',now[2*i] = s[i-1];
   now[len=len*2+1] = '%';
   int pos = 0,R= 0;
   for(int i = 1;i<=len;++i){
    if(i<R) p[i] = min(p[2*pos - i ],R-i);else p[i] = 1;
    while(1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]]==now[i+p[i]]) p[i]++;
    if(i+p[i]>R) {pos = i;R = i+p[i];}
   }
   int MAX = 0;
   for(int i = 1;i<=len;++i) MAX = max(MAX,p[i]-1);
   if(MAX<2) {
    printf("No solution!\n");
   }
   else {
        int xb = 0;
      for(int i = 1;i<=len;i++){
            if(i%2==0&&MAX==2) continue;
            if(p[i]-1==MAX){
                //dbg(MAX);
                //dbg(i);
            if(i%2==1) xb=i;
              else   xb = i;
           //dbg(xb);
                break;
            }
        }
        //if(MAX%2==0)
        int flag = 0;
        if(xb%2==1) flag = 1;
         printf("%d %d\n",xb/2-(MAX/2)-1+flag,xb/2+((MAX)/2)-1);
     for(int i = xb/2-((MAX)/2)-1+flag;i<=xb/2+((MAX)/2)-1;i++)
        printf("%c",to[s[i]-'a']);
     printf("\n");
   }
}
int main(){
   char str[20];
   while(scanf("%s",str)!=EOF){
        int cnt = 0;
    for(int i = str[0]-'a';i<26+str[0]-'a';i++){
        to[i%26] = 'a'+cnt;
        //dbg(to[i%26]);
        cnt++;
    }
    scanf("%s",s);
    Manacher(s);

   }
   return 0;
}

W

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
using namespace std;
const int MAX_N = 110024;
char str[MAX_N];
int re,p[2*MAX_N+5];
char s[MAX_N+5],now[MAX_N+5];
int Manacher(char *s){
   int len = strlen(s);
   for(int i = 1;i<=len;i++) now[2*i-1] = '%',now[2*i] = s[i-1];
   now[len = len*2+1] = '%';
   int pos = 0,R = 0;
   for(int i = 1;i<=len;++i){
    if(i<R) p[i] = min(p[2*pos-i],R-i);else p[i] = 1;
    while(1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]]==now[i+p[i]]) p[i]++;
    if(i+p[i]>R) {pos = i;R = i+p[i];}
   }
   int MAX = 0;
   for(int i = 1;i<=len;++i) MAX = max(MAX,p[i]-1);
   return MAX;
}

int main(){
   while(scanf("%s",str)!=EOF){
    memset(p,0,sizeof(p));
    printf("%d\n",Manacher(str));
   }
   return 0;
}

X

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 100024;
char mo[MAX_N],str[MAX_N];
int Next[MAX_N];
int n2,n1;
void getnext(){
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||mo[i]==mo[j]){++i,++j,Next[i]=j;}
    else j = Next[j];
   }
   return;
}
int kmp(){
   int i = 0,j = 0;
   int ans = 0;
   while(i<n1){
    if(str[i]>='A'&&str[i]<='Z') str[i]+=32;
    if(j==-1||str[i]==mo[j]){++i,++j;}
    else j = Next[j];
    if(j==n2) ans++;
   }
   return ans;
}
int main(){
    long long ans = 0;
    Next[0] = -1;
    mo[0] = 'd';
    mo[1] = 'o';
    mo[2] = 'g';
    mo[3] = 'e';
    mo[4] = '\0';
    getnext();
    n2=4;
   while(scanf("%s",str)!=EOF){
    n1 = strlen(str);
    ans+=kmp();
   }
   printf("%I64d\n",ans);
   return 0;
}

Y

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
using namespace std;
const int MAX_N = 1000024;
int Next[MAX_N];
void getnext(string str){
   int n2 = str.length();
   int i = 0,j = -1;
   while(i<n2){
    if(j==-1||str[i]==str[j]){++i,++j,Next[i]=j;}
    else j = Next[j];
   }
   return ;
}
int kmp(string str,string s2){
   int i = 0,j = 0,len = str.length(),l2 = s2.length();
   while(i<len){
    if(j==-1||str[i]==s2[j]) {++i,++j;}
    else j= Next[j];
    if(j==l2) return 1;
   }
   return 0;
}
int main(){
   int t;
   cin >> t;
   string s;
   while(t--){
    cin >> s;
    Next[0] = -1;
    getnext(s);
    int len = s.length();
    //for(int i = 1;i<=len;i++)
        //dbg(Next[i]);
    int tmp = Next[len];
    //dbg(tmp);
    string str_now = s.substr(0,tmp);
    Next[0] = -1;
    getnext(str_now);
    //dbg(str_now);
    int maxx = 0;
    while(tmp!=0){
            //dbg(s.substr(tmp,len-2*tmp));
    if(kmp(s.substr(tmp,len-2*tmp),str_now)) {
        maxx = tmp;
        break;
    }
    tmp = Next[tmp];
    }
    cout << maxx << endl;
   }
   return 0;
}

猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/81675561