題意:
給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。
題目已經給的很明白了好嘛?
串長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 做一遍類...