HDU6153 A Secret 擴充套件KMP

2021-08-07 05:26:43 字數 1658 閱讀 1169

記錄乙個菜逼的成長。。

題目鏈結

給你乙個字串

s ,乙個字串p.

問p的所有字尾字串在

s中出現的次數乘上相應字尾字串的長度的和

sample input:

abababab

aba

suffix(s2,1) = 「aba」,

suffix(s2,2) = 「ba」,

suffix(s2,3) = 「a」.

n1 = 3,

n2 = 3,

n3 = 4.

l1 = 3,

l2 = 2,

l3 = 1.

ans = (3*3+3*2+4*1)%1000000007.

先將兩個字串都re

vers

e 一下,那麼第二字串的字尾現在變成了字首。

跑一遍擴充套件km

p 求出e

x[i]

陣列 := 表示s[

i…le

ns−1

] 與p[

0…le

np−1

] 的最長公共字首長度

比如翻轉後s=

baba

baba

,p=a

ba e

x[1]

=3.

可以說明

a ,ab

,aba

都至少出現了一次,對答案的貢獻是1+

2+3 ,也就是ex

[i]∗

(ex[

i]+1

)/2

實際上這裡

a 在s[

1…3]

這裡出現了兩次,不要擔心。在ex

[3]=

3 時,會算上。所以是不會漏的。

ps:對字串的套路知之甚少。。orz.為什麼你們什麼都會。

#include 

using

namespace

std;

#define cl(a,b) memset(a,b,sizeof(a))

typedef

long

long ll;

const

int inf = 0x3f3f3f3f;

const

int mod = 1e9 + 7;

const

int maxn = 1000000 + 10;

char s[maxn],p[maxn];

int _next[maxn],ex[maxn];

/*** 擴充套件kmp演算法

**///next[i]:x[i...m-1]與x[0...m-1]的最長公共字首

//extend[i]:y[i...n-1]與x[0...m-1]的最長公共字首

void getnext(char x,int m,int next)

}}void ekmp(char x,int m,char y,int n,int next,int extend)

}}int main()

printf("%lld\n",ans % mod);

} return

0;}

HDU 6153 A Secret 擴充套件KMP

題目鏈結 給定兩個串,求其中乙個串s的每個字尾在另乙個串t中出現的次數乘以其長度之和。擴充套件kmp模板題,將s和t串都逆序以後就變成了求字首的問題了,擴充套件kmp求處從i位置開始的最長公共字首存於陣列,最後通過將陣列的值不為0的進行乙個等差數列和的和就可以了。include include in...

HDU 6153 A Secret 擴充套件kmp

題意 對於s2的每乙個字尾,假設長度為l,在s1出現的次數為k,求l k的和 題解 我們把兩個串都倒過來,變為s1,s2,那麼問題就變為,對於s2的字首匹配s1的每個位置的字尾的總匹配長度和,舉個栗子,s1 aaa s2 aa 那麼在s1的位置1,能匹配的長度有1 2,因此我們擴充套件kmp求出最長...

HDU 6153 A Secret 擴充套件KMP

題意 在母串中找模式串的所有字尾的匹配次數,並乘上各種字尾對應長度,再把所有的結果加起來 1e9 7輸出。思路 把兩個字串都反轉一下就變成了字首匹配,就可以利用擴充套件kmp的性質了。因為extend i 表示的是從i到結尾的主串與模式串的最長公共字首,這樣遍歷一遍主串,每一位對答案的貢獻就是1 e...