设
F
(
x
)
=
∑
i
=
0
∞
P
(
长
度
为
i
时
结
束
)
x
i
F(x)=\sum_{i=0}^{\infty} P(长度为i时结束)x^i
F(x)=∑i=0∞P(长度为i时结束)xi
G
(
x
)
=
∑
i
=
0
∞
P
(
长
度
为
i
时
未
结
束
)
x
i
G(x)=\sum_{i=0}^{\infty} P(长度为i时未结束)x^i
G(x)=∑i=0∞P(长度为i时未结束)xi
∵
P
(
长
度
为
i
时
结
束
)
+
P
(
长
度
为
i
时
未
结
束
)
=
P
(
长
度
为
i
−
1
时
未
结
束
)
\because P(长度为i时结束) +P(长度为i时未结束)=P(长度为i-1时未结束)
∵P(长度为i时结束)+P(长度为i时未结束)=P(长度为i−1时未结束)
∴
F
(
x
)
+
G
(
x
)
=
G
(
x
)
x
+
1
\therefore F(x)+G(x) = G(x)x + 1
∴F(x)+G(x)=G(x)x+1
∴
F
′
(
x
)
+
G
′
(
x
)
=
G
(
x
)
x
+
G
(
x
)
\therefore F'(x)+G'(x)=G(x)x+G(x)
∴F′(x)+G′(x)=G(x)x+G(x)
∴
F
′
(
1
)
=
G
(
1
)
\therefore F'(1) = G(1)
∴F′(1)=G(1)
∵
E
=
∑
i
=
0
∞
i
∗
P
(
长
度
为
i
时
结
束
)
=
(
x
F
′
(
x
)
)
∣
x
=
1
=
F
′
(
1
)
\because E = \sum_{i=0}^{\infty} i*P(长度为i时结束) = (xF'(x))|_{x=1} = F'(1)
∵E=∑i=0∞i∗P(长度为i时结束)=(xF′(x))∣x=1=F′(1)
∴
E
=
G
(
1
)
\therefore E = G(1)
∴E=G(1)
后面的过程比较抽象,开始说人话:
B
o
r
d
e
r
Border
Border是指一个字符串中
s
[
1....
k
]
=
s
[
n
−
k
+
1.....
n
]
s[1....k] = s[n-k+1.....n]
s[1....k]=s[n−k+1.....n]也就是相等的前后缀。
设
s
s
s为名字的字符串。
一个没有结束的串
a
a
a,我们考虑如何让它变成一个结束的串。
显然我们要考虑一个结束的串
b
b
b是怎么从没有结束的串变来的。
我们发现
b
b
b的后面是一个
s
s
s,设去掉
s
s
s后
b
b
b变成了
a
a
a。
那么
F
(
x
)
=
G
(
x
)
∗
1
m
∣
s
∣
∗
x
∣
s
∣
?
F(x) = G(x) * \frac 1{m ^ {|s|}} * x^{|s|}?
F(x)=G(x)∗m∣s∣1∗x∣s∣?
发现可能在加入
s
s
s的一个前缀的时候就构成了
s
s
s。
需要排除这种情况。
发现这种情况需要
s
s
s的前缀是
b
o
r
d
e
r
border
border,
a
a
a的后缀是
s
s
s去掉那个
b
o
r
d
e
r
border
border后的串。
F
(
x
)
=
G
(
x
)
∗
1
m
∣
s
∣
∗
x
∣
s
∣
−
∑
s
[
1...
i
]
i
s
a
b
o
r
d
e
r
F
(
x
)
∗
(
x
m
)
∣
s
∣
−
i
F(x) = G(x) * \frac 1{m ^ {|s|}} * x^{|s|} - \sum_{s[1...i] \ is \ a \ border}F(x) * \left({\frac {x}{m}}\right)^{|s|-i}
F(x)=G(x)∗m∣s∣1∗x∣s∣−∑s[1...i] is a borderF(x)∗(mx)∣s∣−i
我们需要求
G
(
1
)
G(1)
G(1)就令
x
=
1
x=1
x=1,又因为
F
(
1
)
=
1
F(1) = 1
F(1)=1
G
(
1
)
=
m
∣
s
∣
+
∑
s
[
1...
i
]
i
s
a
b
o
r
d
e
r
m
i
G(1) = m^{|s|}+ \sum_{s[1...i] \ is \ a \ border}m^{i}
G(1)=m∣s∣+∑s[1...i] is a bordermi
如果我们把原串也看作一个
b
o
r
d
e
r
border
border
就是
E
=
G
(
1
)
=
∑
s
[
1...
i
]
i
s
a
b
o
r
d
e
r
m
i
E = G(1) = \sum_{s[1...i] \ is \ a \ border}m^{i}
E=G(1)=∑s[1...i] is a bordermi
然后KMP求
b
o
r
d
e
r
border
border就行,注意这个KMP和一般的不一样
AC Code:
#include<bits/stdc++.h>
#define maxn 100005
#define mod 10000
using namespace std;
int n,t,pw[maxn],a[maxn],nxt[maxn];
int main(){
scanf("%d%d",&n,&t);
pw[0] = 1;
for(int i=1;i<=100000;i++) pw[i] = pw[i-1] * 1ll * n % mod;
for(int m;t--;){
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
nxt[0] = -1;
for(int j=0,k=1;k<=m;)
if(j==0 || a[k] == a[j]) nxt[k++] = j++;
else j = nxt[j-1]+1;
int ans = 0;
for(int i=m;i;i=nxt[i])
ans = (ans + pw[i]) % mod;
printf("%04d\n",ans);
}
}