BZOJ 4566 找相同字串

2021-09-18 04:34:05 字數 2950 閱讀 4064

題意:

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

題目已經給的很明白了好嘛?

串長n≤2×

10

5n\leq 2\times 10^5

n≤2×10

5sol:

先考慮n

3n^3

n3暴力,分別列舉串1和串2字尾的左端點,然後暴力比較。

優化一下,求的是兩個suf

sufsu

f的lc

plcp

lcp,可以把倆串用別的字元隔開,然後做sasa

sa查詢o(1

)o(1)

o(1)

,總複雜度o(n

2)

o(n^2)

o(n2)

繼續觀察,是結合的串的左半區間對右半區間每個點對rkrk

rk對映以後的答案

也就是對於左右各半區間不能包含自己。

考慮子區間最小值的和減去左右各半子區間最小值的和,做三遍sasa

sa就完了。

子區間最小值的和可以單調棧維護,原理是乙個點控制的最小值範圍。

接近 bzoj 3238這題。

#include

#include

#include

#include

const

int n =

2e5+7;

const

int lim =

2e5;

typedef

long

long ll;

inline

intmax

(int a,

int b)

inline

intmin

(int a,

int b)

int x[n*2]

, y[n*2]

, sa[n*2]

, rk[n*2]

, c[n*2]

;int m = lim, n;

char ssa[n*2]

, ssb[n*2]

;int het[n*2]

, qlog[n*2]

, st[n*2]

[23];

//#define r register

int ss[n*2]

;inline

void

getsa()

int k =0;

memset

(het,0,

sizeof

(het));

for(

int i =

1; i <= n; i++

) rk[sa[i]

]= i;

for(

int i =

1; i <= n; i++)if

(rk[i]!=1

) qlog[1]

=0;memset

(st,0,

sizeof

(st));

for(

int i =

2; i <= lim; i++

) qlog[i]

= qlog[i /2]

+1;for

(int i =

1; i <= lim; i++

) st[i][0

]= het[i]

;int logw = qlog[n]

;for

(int i =

1; i <= logw; i++

)for

(int j =

1; j +(1

<< i)-1

<= n; j++

) st[j]

[i]=

min(st[j]

[i -1]

, st[j +(1

<<

(i -1)

)][i -1]

);}const

int inf =

1e9+7;

inline

intquery

(int x,

int y)

int t;

int lena, lenb;

int stack[n*2]

, top, l[n*2]

, r[n*2]

;ll ans;

inline

void

solve1

(int x)

while

(top) r[stack[top--]]

= n +1;

for(

int i =

1; i <= n; i++

) ans +

= x *

(ll)

(r[i]

- i)

*(ll)

(i - l[i])*

(ll)het[i];}

intmain()

m =200,

getsa()

;solve1(1

);for(

int i =

1; i <= lena; i++

) ss[i]

= ssa[i]

; n = lena, m =

200;

getsa()

,solve1(-

1);for

(int i =

1; i <= lenb; i++

) ss[i]

= ssb[i]

; n = lenb, m =

200;

getsa()

,solve1(-

1); printf (

"%lld"

, ans)

;return0;

}

bzoj4566 找相同字元

題意 給定兩個字串,從中各取乙個子串使之相同,有多少種取法。允許本質相同。解 建立廣義字尾自動機,對於每個串,分別統計cnt,之後每個點的cnt乘起來。記得開long long 1 include 2 include 3 include 4 5 typedef long long ll 6 cons...

BZOJ4566 找相同字元(字尾陣列)

bzoj 字尾陣列的做法,應該不是很難想 首先看到兩個不同的串,當然是接在一起求sa hei ght 那麼,考慮一下暴力 在兩個串各列舉乙個字尾,他們的lc p 就是對答案產生的貢獻 現在優化一下,按照sa 的順序列舉來處理lc p 利用乙個單調棧維護一下,每次記錄一下前面有多少個的貢獻和當前答案一...

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

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