給定兩個字串,要求相同子串的個數,其中字串開始的位置不同則為不同的子串。
思路:第一肯定是想到的字尾陣列,求得的是high陣列,那麼這只是排列臨近的的字尾的最長公共字首,為了求總的個數,我們可以對high陣列進行分段求得,就是從1到n列舉最長公共字首的長度,然後進行分段,要注意相同的子串必須屬於不同的字串的,具體看**,表達能力太差啊!
#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define rep(i,n) for(int i=0; i=(m); --i)
#define ll long long
#define arc(a) ((a)*(a))
#define inf 100000
#define exp 0.000001
#define n 200005
char s[n*2];//陣列的長度要為兩倍的
int n,m;//n全域性變數為字元陣列的長度的
int sa[n*2],high[n*2],rank[n*2],tmp[n*2],top[n*2];
int len1;
struct node;
int pre[n*2];
node a[n*2];
void makesa()
}void lcp()
ll work()
if(sa[i-1]<=len1) pre[tp]=1;
if(sa[i-1]>len1) pre[tp]=2;
sum[pre[tp]]+=high[i]-m+1;
int t;
a[tp].cont=high[i]-m+1;
if(sa[i]<=len1) t=1;
if(sa[i]>len1) t=2;
ans+=sum[3-t];
tp++;
} return ans;
}int main()
{ while(scanf("%d",&m))
{ if(m==0) break;
scanf("%s",s);
int len=strlen(s);
len1=len;
s[len]='$';
scanf("%s",&s[len+1]);
makesa();
lcp();
cout<
字尾陣列處理多字串公共子串總結
關於字尾陣列的學習可以參考 字尾陣列學習小記 模板 whyorwhnt的專欄 個人經驗 對單個字串問題求個數需要列舉,求長度可以利用二分 公共子串 如果字串l同時出現在字串a和字串b中,則稱字串l是字串a和字串b的公共子串。與子串行不同的是,子串行可以斷續,通常用dp解決,子串要求連續。字尾陣列可以...
POJ 2217 字尾陣列 最長公共子串
題目鏈結 題目大意 求兩個串的最長公共子串,注意子串是連續的,而子串行可以不連續。解題思路 字尾陣列解法是這類問題的模板解法。對於n個串的最長公共子串,這要把這些串連在一起,中間用 這類的特殊符號分隔一下。先求字尾陣列,再求最長公共字首,取相鄰兩個且屬於不同串的sa的最大lcp即可。原理就是 這樣把...
字尾陣列求最長公共子串 POJ 2774
根據羅的 兩個串的中間要加乙個ascii碼比任何字母都小的字元 最長公共子串 pku2774,ural1517 給定兩個字串a 和b,求最長公共子串。演算法分析 字串的任何乙個子串都是這個字串的某個字尾的字首。求a 和b 的最長公共子串等價於求a 的字尾和b 的字尾的最長公共字首的最大值。如果列舉a...