NOIP模擬 字串(字尾陣列)

2021-08-10 14:31:45 字數 1357 閱讀 1365

給定兩個字串 s1 和 s2 ,兩個字串都由 26 個小寫字母中的部分字母構成。現在需要統計 s_2 在 s_1 中出現了的次數。

對於 s1 中的每個位置 i ,設 st

rlen

(s2)

=m,若: ∑j

=1m[

s1[i

+j−1

]!=s

2[j]

]≤k

(最外層中括號為布林表示式)

則認為 s2 在 s1 的 i 處出現了一次,現在想知道,s2 在 s1 中一共出現了多少次? (

strlen(

s1)≤

200000,s

trle

n(s2

)≤100000,k

≤100

)

題解:字尾陣列。

每個位置求k次最長公共字首,字尾陣列+st表o(

1)查詢,時間複雜度o(

nk)

#include

typedef

unsigned

long

long ull;

typedef

unsigned

int uint;

using

namespace

std;

const

int maxn=2e5+50;

const

int base=31;

char s[maxn],t[maxn];

char ss[maxn<<1];

int k,lenss,lens,lent,ht[maxn<<1][20],log[maxn<<1];

int m,c[maxn<<1],a[maxn<<1],b[maxn<<1],*rk=a,*sa2=b,sa[maxn<<1];

inline

int findpos(int bg1,int bg2)

inline

void rsort()

inline

void getsa()

for(int i=1,k=0,j;i<=lenss;ht[rk[i++]][0]=k)

for((k?k--:0),j=sa[rk[i]-1];ss[i+k]==ss[j+k];++k);

}inline

void pre()

int main()

nowpos=p+2;

}if(bz)++ans;

else

if(findpos(nowpos,nowpos-i+1)>=i+lent-1)++ans;

}cout

<}

字串 字尾陣列

n 字串的長度。m 當前字尾 離散化後 的值域。對於char可以跳過離散化,初值取128即可,對於int要離散化,初值取n即可,初值要保證覆蓋整個值域。sa i 排名為 i 的字尾的起始位置。rk i 起始位置為 i 的字尾的排名。驗證 const int maxn 1000000 10 int n...

字尾陣列 用字尾處理字串

字尾陣列處理的是文字串。我們將文字串的每一條字尾拿出來,按照字典序排序,然後就可以處理字尾陣列了。字尾陣列sa i 表示的就是排名第i位的字尾的第乙個字元所在下標。這可能有點繞口,所以我們用樣例解釋一下,如對於文字串ababa,則字尾為ababa,baba,aba,ba,a,我們排序後就是 a,ab...

字串演算法之後綴陣列

字串演算法一直是我最不願碰的東西,包括dp。ababs 中所有的字尾串為 ababs babs abs bs s 我們按照字典序排列即為 ababs abs babs bs s 而字尾陣列就是用來求字尾的字典序的 sa i 為排名為i的字尾第乙個字元在主串裡的位置.譬如上面的例子 sa 1 1,sa...