AHOI 2013 差異 題解

2021-10-05 15:50:24 字數 1841 閱讀 6005

題目傳送門

題目大意:給出乙個字串,求出這個柿子的值:∑1≤

i

nlen

(ti)

+len

(tj)

−2×l

cp(t

i,tj

)\sum\limits_ 2

2(n−1)

×n×(

n+1)

​。然後考慮後面如何求出任意兩個字尾的最長公共字首之和,把串反過來,就變成了求任意兩個字首的最長公共字尾。

建出sam,考慮每乙個狀態的貢獻,假設乙個狀態的 end

po

sendpos

endpos

集大小為 siz

e[i]

size[i]

size[i

],就說明其中任意乙個子串都恰好出現過 siz

e[i]

size[i]

size[i

] 次,對於任意乙個子串,假設他在 [a,

b]

[a,b]

[a,b

] 和 [c,

d]

[c,d]

[c,d

] 出現過,那麼以 b

bb 結尾和以 d

dd 結尾的字首的最長公共字尾至少會延伸到 a,c

a,ca,

c 這兩個位置,所以可以提供 1

11 的貢獻,至於在 a+1

a+1a+

1 和 c+1

c+1c+

1 位置的匹配,自然會有 [a+

1,b]

[a+1,b]

[a+1,b

] 和 [c+

1,d]

[c+1,d]

[c+1,d

] 兩個子串來提供貢獻 ,一共有 siz

e[i]

×(si

ze[i

]−1)

size[i]\times(size[i]-1)

size[i

]×(s

ize[

i]−1

) 種這樣的情況,所以貢獻就是 siz

e[i]

×(si

ze[i

−1])

size[i]\times (size[i-1])

size[i

]×(s

ize[

i−1]

)。而乙個狀態內有 len

(i)−

len(

link

(i))

len(i)-len(link(i))

len(i)

−len

(lin

k(i)

) 個子串,所以貢獻再乘上這個數量即可。

**如下:

#include

#include

#include

using

namespace std;

#define maxn 1000010

#define ll long long

int n;

char s[maxn]

;struct statest[maxn]

;int id=

0,last=

0,now,p,q;

int size[maxn]

;void

extend

(int x)

} last=now;

}int c[maxn]

,a[maxn]

;void

get_size()

intmain()

題解 AHOI2013 作業(莫隊)

有一段時間沒寫莫隊,今天wzb分享這道題,ssw02一看,我可以用莫隊水,寫的挺快的 歡迎 ssw02的部落格 給定長為n的序列 m個詢問,每次詢問在 下標在 l r 之間 數值在 a b 之間的數的種類和總數 n,m都是在1e5 的範圍內 可以離線,資料支援根號演算法,所以我們可以考慮分塊 總數和...

AHOI2013 找硬幣(搜尋)

time limit 10 sec memory limit 64 mb submit 348 solved 114 submit status 小蛇是金融部部長。最近她決定製造一系列新的貨幣。假設她要製造的貨幣的面值為x1,x2,x3 那麼x1必須為1,xb必須為xa的正整數倍 b a 例如1,5...

BZOJ3238 AHOI2013 差異 題解

參考 第一道接觸字尾樹的題,然而不想講這個東西。我們只需要知道將串倒著建字尾自動機parent樹就是字尾樹即可。然後兩個字尾的lcp就是他們的lca的len。設點u,則過點u的字尾就有su子樹的size和個,所以能配出size u size u 1 2個對,這條路徑的長度貢獻為 tr u l tr ...