找相同字元 字尾自動機

2021-09-25 19:39:40 字數 1330 閱讀 6616

題意:給定兩個字串,在兩個字串中任選子串,求兩子串相同的方案數

思路:用字尾自動機處理兩個字串,一般考慮在中間插入乙個用不到的字元(比如』#』),然後將它們組成乙個串(後來發現好像不能插』#』,畢竟我陣列第二維只開了26的大小;然後有乙個方法就是把陣列開成27的,然後插入乙個數字26就行了)

分別記錄每個節點有多少個屬於第乙個字串和第二個字串的endpos,最後累加答案即可

注意爆int,疊加答案採用 1ll

∗cnt

[i][

0]∗c

nt[i

][1]

∗(le

n[i]

−len

[fa[

i]])

1ll*cnt[i][0]*cnt[i][1]*(len[i]-len[fa[i]])

1ll∗cn

t[i]

[0]∗

cnt[

i][1

]∗(l

en[i

]−le

n[fa

[i]]

)給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。

兩行,兩個字串s1,s2,長度分別為n1,n2。1 <=n1, n2<= 200000,字串中只有小寫字母

輸出乙個整數表示答案

輸入aabb

bbaa

輸出10

//#pragma comment(linker, "/stack:102400000,102400000")

#include "bits/stdc++.h"

#define pb push_back

#define ls l,m,now<<1

#define rs m+1,r,now<<1|1

#define hhh printf("hhh\n")

#define see(x) (cerr<<(#x)<<'='<<(x)inline int read()

const int maxn = 1e6+10;

const int mod = 1e9+7;

const double eps = 1e-9;

char s0[maxn], s1[maxn];

int ch[maxn][27], fa[maxn], len[maxn];

int last=1, sz=1;

int cnt[maxn][2];

int a[maxn], c[maxn];

void add(int c, int f)

}}int main()

BZOJ4566 找相同字元(字尾自動機)

bzoj 看到多串處理,sa 就連起來 sa m?單串建自動機 然後其他串匹配 對於乙個串建完sa m 後 另乙個串在sa m 上匹配 記錄當前匹配的最大長度 匹配了當前位置的話,就能產生一定的貢獻 但是很顯然,沿著pa rent 往上,所有點都能夠產生貢獻 所以匹配完再沿著pa rent 做一遍類...

BZOJ4566 找相同字元 字尾自動機

題意 給定兩個字串,求兩個字串相同子串的方案數。分析那麼將字串s1建sam,然後對於s2的每個字首,都在sam中找出來,並且計數就行。我一開始的做法是,建乙個u和len,順著s2跑sam,當st u next c 存在的時候,u st u next c len 這時候找到了這個字首的最長公共字尾,然...

字尾自動機

基礎知識 step i 表示的是字串i在原字串中的位置。pareint i 表示root到parent i 的子串是root到i的最長字尾。字尾自動機遍歷可以得到原字串的所有子串。特殊技巧 一 字尾自動機的不同子串數有兩種求法 1.ans step i step parent i 1 i cnt 2...