CTS2019 重複(KMP自動機dp)

2021-09-24 15:52:15 字數 1545 閱讀 7959

傳送門.

我這麼菜怎麼可能會標算的神仙解法?

我們發現如果直接考慮有乙個子串不妨轉換為沒有子串合法的意思是假設現在匹配了s[1…x],新加乙個字元c,不存在s

[1..y]

=s[x

−y

+1..x]

,且s[

y+1]

>c(

y可以=

0)

s[1..y]=s[x-y+1..x],且s[y+1]>c(y可以=0)

s[1..y

]=s[

x−y+

1..x

],且s

[y+1

]>c(

y可以=

0)那這個東西怎麼計數呢?

如果已經有無限個t拼起來,再加乙個t,在自動機上的點不會變。

也就是從自動機上乙個點出發,走完t之後,回到原點的方案數。

那麼只需要列舉起點,就可以得到乙個o(n

2m

)o(n^2m)

o(n2m)

的做法。

再想想有什麼美妙的性質,乙個點的合法出邊中,只有至多一條不是轉移到0的,這個結論可以由合法邊的判定得到。

那麼列舉這個點走了多少步走到0,後面的事情只用對0做乙個預處理的dp。

code:

#include

#define fo(i, x, y) for(int i = x, b = y; i <= b; i ++)

#define ff(i, x, y) for(int i = x, b = y; i < b; i ++)

#define fd(i, x, y) for(int i = x, b = y; i >= b; i --)

#define ll long long

#define pp printf

#define hh pp("\n")

using namespace std;

const

int n =

2005

;int m, n;

char s[n]

;int nt[n]

, to[n][26

];const

int mo =

998244353

;ll f[n]

[n], ans;

intmain()

fo(i,

0, n)

} f[0]

[0]=

1;fo(i,

0, m -1)

}fo(j,0

, n) f[i +1]

[j]%

= mo;

} ans =1;

fo(i,

1, m) ans = ans *

26% mo;

fo(i,

0, n)

if(x == i) ans --;}

ans =

(ans % mo + mo)

% mo;pp(

"%lld\n"

, ans)

;}

hihocoder 字尾自動機四 重複旋律6

題目 對於 k in 1,n 求出長度為 k 的子串出現次數最多的出現了多少次 我直到現在才理解字尾自動機上的子樹和是什麼意思 非常顯然的一點是 endpos link u endpos u 考慮到 link u 有多個兒子 於是還需要 endpos 的另外乙個性質 endpos u endpos ...

hihocoder 字尾自動機四 重複旋律7

題目 在 dag 上跑乙個 dp 就好了 設 ans i 表示到了 sam 的 i 位置上所有的子串形成的數的和,之後我們順便記錄乙個方案數 d i 之後我們直接轉移就好了 ans v ans u times 10 w u,v times d u d v d u 答案是 sum ans i incl...

BZOJ 字尾自動機四 重複旋律7

時間限制 15000ms 單點時限 3000ms 記憶體限制 512mb 描述小hi平時的一大興趣愛好就是演奏鋼琴。我們知道一段 旋律可以被表示為一段數構成的數列。神奇的是小hi發現了一部名字叫 十進位制進行曲大全 的作品集,顧名思義,這部作品集裡有許多作品,但是所有的作品有乙個共同特徵 只用了十個...