#include#include#define maxn 100010
using namespace std;
int next[maxn];
char s[maxn];
char p[maxn];
void prekmp(char x,int m,int next )
}return ans;
}//計數 不可重複
int kmpcount(char pp,int m,char ss,int n)
}return ans;
}//返回位置
int kmp(char pp,int m,char ss,int n)
}return -1;
}
題意就是給你兩個序列,讓你求b序列在a序列第一次出現(完全相同)的下標
這道題是一道板子題,直接用返回位置的那個板子貼上就過了,不過還是要注意細節問題,輸入輸出盡量用printf、scanf,不然會tle,開陣列卡著邊界開,不然會mle,另外注意輸入輸出格式 ,不然會pe。**在下面?
#include#include#includeconst int maxn = 1e6+5;
using namespace std;
int next[maxn];
int pat[maxn];
int str[maxn];
void prekmp(int x,int m,int next)
}return -1;
}int main()
}return ans;
}int main()
}return ans;
}int main()
return 0;
}
題意為新增最少的字元使原字串變成週期至少為2的迴圈字串
這道題利用了next陣列的特性,結論是長度為m的pattern串的迴圈結長度為m-next[m]
**如下:
#include#include#includeusing namespace std;
const int maxn = 100005;
int next[maxn];
char pat[maxn];
void prekmp(char x,int m,int next)
}return 0;
}
本題題意為求m個字串長度至少為3的最長公共子串
由於m只有10而且len小於60,我們可以選擇列舉某乙個串的子串並用str.find()或者kmp驗證是否所有該子串在所有字串**現過,也可以用經典的二分長度將height陣列分塊的字尾陣列做法
poj3080(find解法
//由於只查詢是否出現過,演算法複雜度差距不大,所以這裡給出簡單一些的寫法
#include#include#include#includeusing namespace std;
const int maxn = 65;
char str[maxn];
string ansstr;
string str2[maxn];
int main()
void getsa(int *r,int *sa,int n,int m)
}void getheight(int *r,int n)
i++;
}if(!vis[belong[sa[i-1]]])
if(cnt>=t)
}return false;
}int main()
if(r<3) printf("no significant commonalities \n");
else
if(ans==0)
for(int i=0;i
本題題意為求字串的每個字首在整個字串中的出現次數。
我們想象性質二,如果next[j]對答案有乙個貢獻,那麼這個貢獻在j中一定會再貢獻一次,而且j為結尾的字串對於總串產生的貢獻只有長度為j的子串,於是我們可以得到轉移方程ans[j]=ans[next[j]]+1ans[j]=ans[next[j]]+1,最後對所有字首的貢獻取和即為答案。
hdu3336**
#include#include#include#includeusing namespace std ;
const int maxn = 1e6+5;
int next[maxn];
char str[maxn];
char mo[maxn];
int dp[maxn];
int n1,n2;
void getnext()
for(int i=0;i多個字串的最長公共子串,只不過子串可以逆置出現,只要把第八題的做法反過來再找一次就好,直接上**
#include#include#include#includeusing namespace std;
const int maxn = 105;
char str[maxn];
string ansstr;
string str2[maxn];
int main()
}return i0)
else if(i+k+1 > j) i = i+k+1;
else i = j+1;
k = 0;}}
return i < j ? i : j;
}int ans[maxn];
int main()
else
}return 0;
}
本題為給你n個01串,可以對每個串旋轉任意次,求最少出現多少個不同的字串,我們可以知道,如果兩個字串是可以旋轉之後相同的,那麼他們的最小表示法一定是相同的,所以我們可以求出所有字串的最小表示法,然後用乙個set去重就好了。
hdu2609**
#include#include#include#include#includeusing namespace std;
int getmin(char *s)
}return is;
int main()
return 0;
}
未完待續。。。 拓展KMP以及模板
廢話不多說,上模板 includeconst int maxn 1e6 10 int next maxn extend maxn mol,strl next陣列 extend陣列 模式串長度 母串長度 char mo maxn s maxn 模式串 母串 void getnext 求解模式串 mo ...
KMP模板 和入門題
hdu1711 題意就是給你兩個序列,讓你求b序列在a序列第一次出現 完全相同 的下標 本題就是kmp的模板題,將i指標指向a串,將j指標指向b串,如果匹配就繼續下一位的匹配,如果不匹配,將j跳轉到next j 繼續向前匹配。include define inf 0x3fffffff define ...
拓展KMP演算法 入門 模板
擴充套件kmp演算法,圖很形象,寫的也很清晰,下面的模板就是出自該部落格文章。拓展kmp是求母串s長度為n和子串t長度為m,求s的每乙個字尾子串與t的字首子串匹配的最長長度。求解模式串t的next陣列,這個函式和下面的函式幾乎相同 void getnext string t,int m,int ne...