pku 3415 字尾陣列,公共子串統計

2021-06-18 06:15:06 字數 1245 閱讀 2436

給定兩個字串,要求相同子串的個數,其中字串開始的位置不同則為不同的子串。

思路:第一肯定是想到的字尾陣列,求得的是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...