HDU 5769 Substring(字尾陣列)

2022-05-14 11:23:31 字數 896 閱讀 3197

求字串 \(s\) 本質不同且一定包含字元 \(x\) 的子串個數。

\(1 \leq |s| \leq 10^5\)

求乙個長度為 \(n\) 的串 \(s\) 本質不同的子串個數可以使用公式 \(\displaystyle\sum_^ n-sa[i]+1-h[i]\) ,其中 \(h[0]=1\)。

這個公式是比較好證的。字尾的字首就是子串,我們分析每個字尾有多少個對答案有貢獻的字首,\(n-sa[i]+1\) 表示所有字首的個數, \(h[i]\) 即 \(\text(sa[i],sa[i-1])\) ,表示前面出現過重複的字首個數,減掉即可。

那有了乙個出現 \(x\) 的限制後,這樣分析仍然可行。限制增加了出現 \(x\),那預處理出每個位置往後的第乙個 \(x\)(本身也可以)的位置 \(nxt\) ,然後把要減去的值改成 \(\max(h[i],nxt[sa[i]]-sa[i])\) 即可。

#include#define for(i,x,y) for(int i=(x),i##end=(y);i<=i##end;++i)

#define dor(i,x,y) for(int i=(x),i##end=(y);i>=i##end;--i)

templateinline bool chk_min(t &x,const _t y)

for(i,1,n)rk[sa[i]]=i;

int k=0;

h[1]=0;

for(i,1,n) }

ll query()

int main()

dor(i,n-1,1)chk_min(nxt[i],nxt[i+1]);

printf("case #%d: %lld\n",ti,query());

} return 0;

}

HDU 5769字尾陣列

題意 給你乙個串,問你含某個特定的字元的不同子串有多少種。思路 使用字尾陣列。很久之前看過做過幾個模板水題。以為自己做不到這麼高深的題目。結果這次就卡了,想hash莽一下發現很不科學,就放棄了。看來字尾陣列也已經是標配了。趕緊再補充補充自己。首先退一步講,字尾陣列如何求不同子串個數。其實就是利用排序...

hdu5769Substring 字尾陣列

題意 給你乙個字元x和乙個字串s,問你s中有多少個不相同的子串?且必須含有字元x。題解 1 我們可以利用字尾陣列來做這道題。我們求出我們要的三個陣列ra,sa,height。字尾陣列求出來的三個陣列 2 我們知道乙個字尾能夠貢獻出n sa i 1 height i 個不相同的子串,而我們要包含字元x...

HDU 5769 Substring 字尾陣列

傳送門 思路 不考慮x字元,先考慮怎麼求本質不同的串有幾個,那麼就是列舉一遍height陣列,去掉字首相同的就可以了。我們考慮x字元的話,就要保證所有求得的串都要包含這個字元。那麼我們事先求乙個陣列,pos i 表示當前字元 包括自身 的右邊的第乙個x字元的位置。然後還是列舉height陣列,當前字...