拓展kmp模板
int nx[maxn],ex[maxn]; //nx[i]表示模式串T[i~len-1]与T的最长公共前缀 //ex[i]表示母串S[i~len-1]与T的最长公共前缀 char S[maxn],T[maxn]; int lent,lens; void getNext(){ nx[0]=lent;//本身匹配 int j=0; while(j+1<lent&&T[j]==T[j+1]) j++; nx[1]=j; int k=1;//最远拓展位置的开始位置用k保存 for(int i=2;i<lent;i++){ int p=k+nx[k]-1;//最远拓展位置 int l=nx[i-k];/* 难点:因为 匹配:k~p<->0~p-k+1 那么 i对应i-k 那么next[i-k]就是从i开始去匹配原串(从0位置开始的长度) */ //下面分两种情况讨论: if(i+l<p+1) nx[i]=l;//如果在最远匹配位置之内; else{//如果不在,记得更新; j=max(0,p-i+1); while(i+j<lent&&T[i+j]==T[j]) j++;//看p之外的位置是否匹配; nx[i]=j; k=i; } } } /* 求extend数组和求next数组基本一致; */ void exkmp(){ int j=0; while(j<lens&&j<lent&&S[j]==T[j]) j++; ex[0]=j; int k=0; for(int i=1;i<lens;i++){ int p=k+nx[k]-1; int l=nx[i-k]; if(l+i<p+1) ex[i]=l; else{ j=max(0,p-i+1); while(i+j<lens&&j<lent&&S[i+j]==T[j]) j++; ex[i]=j; k=i; } } } int nx[maxn],ex[maxn]; char S[maxn],T[maxn]; int lent,lens; void getNext(){ nx[0]=lent; int j=0; while(j+1<lent&&T[j]==T[j+1]) j++; nx[1]=j; int k=1; for(int i=2;i<lent;i++){ int p=k+nx[k]-1; int l=nx[i-k]; if(i+l<p+1) nx[i]=l; else{ j=max(0,p-i+1); while(i+j<lent&&T[i+j]==T[j]) j++; nx[i]=j; k=i; } } } void exkmp(){ int j=0; while(j<lens&&j<lent&&S[j]==T[j]) j++; ex[0]=j; int k=0; for(int i=1;i<lens;i++){ int p=k+nx[k]-1; int l=nx[i-k]; if(l+i<p+1) ex[i]=l; else{ j=max(0,p-i+1); while(i+j<lens&&j<lent&&S[i+j]==T[j]) j++; ex[i]=j; k=i; } } }