給定兩個字串 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...