Manacher模板,kmp,扩展kmp,最小表示法模板
2013-07-30 22:47
274 查看
// Manacher算法,很好用。 char s[2*N]; //储存临时串 int save[2*N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); int cnt=0; for(int i=0;i<len;i++) { s[cnt++]='#'; s[cnt++]=tmp[i]; } s[cnt++]='#'; memset(save,0,sizeof(save)); int a=0,p=0; int mx=1; for(int i=1;i<cnt-1;i++) { if(i>=p) { int num=1; while(i+num<cnt&&i-num>=0&&s[i+num]==s[i-num]) { num++; } p=i+num-1; //能到达的最远位置 a=i; save[i]=num-1; //从这个位置出发最长的回文 if(save[i]==0) continue; if(s[i]=='#') { if(2*((save[i]-1)/2 +1)>mx) mx=2*((save[i]-1)/2+1); } else { if(2*(save[i]/2)+1>mx) mx=2*(save[i]/2)+1; } } else { int j=2*a-i; if( i+save[j] < p) { save[i]=save[j]; if(save[i]==0) continue; if(s[i]=='#') { if(2*((save[i]-1)/2 +1)>mx) mx=2*((save[i]-1)/2+1); } else { if(2*(save[i]/2)+1>mx) mx=2*(save[i]/2)+1; } } else { int k=2*i-p; while(p+1<cnt&&k-1>=0&&s[p+1]==s[k-1]) { p++; k--; } a=i; save[i]=p-i; if(save[i]==0) continue; if(s[i]=='#') { if(2*((save[i]-1)/2 +1)>mx) mx=2*((save[i]-1)/2+1); } else { if(2*(save[i]/2)+1>mx) mx=2*(save[i]/2)+1; } } } } return mx; }
kmp,扩展kmp
// 感觉kmp可以理解。 #define N 100010 int s ; int next ; int t ; int main() { //freopen("//home//chen//Desktop//ACM//in.text","r",stdin); //freopen("//home//chen//Desktop//ACM//out.text","w",stdout); int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",s+i); for(int i=0;i<m;i++) scanf("%d",t+i); ///////////////求next int j=0; next[0]=0; for(int i=1;i<m;i++) { while(j!=0&&t[j]!=t[i]) j=next[j-1]; if(t[j]==t[i]) j++; next[i]=j; } ///////////////////// j=0; int ans=-1; for(int i=0;i<n;i++) { while(j!=0&&s[i]!=t[j]) j=next[j-1]; if(s[i]==t[j]) j++; if(j==m) { ans=i+1-m+1; break; } } /////////////////// if(ans==-1) printf("-1\n"); else printf("%d\n",ans); } return 0; } // 扩展kmp。 #defien N 100100 int next ,sum ;// sum用来记录 void build(char s[]) { memset(next,0,sizeof(next)); int p=0,a=0; next[0]=len; for(int i=1;i<len;i++) { if(i+next[i-a]-1<p) { next[i]=next[i-a]; } else { int k=p-i; while(p+1<len && s[p+1]==s[k+1]) { p++; k++; } p=max(p,i); next[i]=k+1; a=i; } } } void extend_kmp(char s[],char t[])//求从s到t上的最大前缀 { memset(sum,0,sizeof(sum)); int p=-1,a=0; for(int i=0;i<len;i++) { if(i+next[i-a]-1<p) { sum[i]=next[i-a]; } else { int k=p-i; while(p+1<len && s[p+1]==t[k+1]) { p++; k++; } p=max(p,i); sum[i]=k+1; a=i; } } }
最小表示法
int mistr(char s[],int len) //输入一串字符,返回最小表示法的起始位置 { int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { if(s[i+k]==s[j+k]) { k++; } else { if(s[i+k] > s[j+k]) i=i+k+1; if(s[i+k] < s[j+k]) j=j+k+1; k=0; if(i==j) j++; } } return min(i,j); }
相关文章推荐
- 最小(大)表示法习题 -- 来自[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher
- HDU 3374 String Problem(最大最小表示法模板+KMP+next数组的运用)
- 字符串同构最小最大表示法模板&&manacher模板
- 【string】KMP, 扩展KMP,trie,SA,ACAM,SAM,最小表示法
- HDU 3374 String Problem (KMP+最小最大表示)
- hdu 3374 String Problem kmp+字符串最小表示法+next数组性质
- HDU 3374 String Problem (KMP+最大最小表示)
- 模板_扩展kmp
- HDU 6153 A Secret(扩展kmp模板题)
- 字符串的最大最小表示法 模板
- 【模板】字符串算法-字符串最小表示法
- KMP模板,最小循环节
- HDU 3374 String Problem (KMP+最大最小表示)
- hdu 3374 String Problem (kmp+最大最小表示法)
- 理解字符串循环同构的最小/最大表示法+模板
- HDU 3374 String Problem (KMP+最大最小表示)
- 扩展KMP模板
- hdu3374最大最小表示+kmp
- HDU 2594 扩展kmp模板题
- zoj 2006 Glass Beads(字符串的最小表示模板题)