z函数(kmp)
P5410 【模板】扩展 KMP/exKMP(Z 函数)
题目描述
给定两个字符串 \(a,b\),你要求出两个数组:
- \(b\) 的 \(z\) 函数数组 \(z\),即 \(b\) 与 \(b\) 的每一个后缀的 LCP 长度。
- \(b\) 与 \(a\) 的每一个后缀的 LCP 长度数组 \(p\)。
对于一个长度为 \(n\) 的数组 \(a\),设其权值为 \(\operatorname{xor}_{i=1}^n i \times (a_i + 1)\)。
输入格式
两行两个字符串 \(a,b\)。
输出格式
第一行一个整数,表示 \(z\) 的权值。
第二行一个整数,表示 \(p\) 的权值。
输入输出样例 #1
输入 #1
aaaabaa
aaaaa
输出 #1
6
21
说明/提示
样例解释:
\(z = \{5\ 4\ 3\ 2\ 1\}\),\(p = \{4\ 3\ 2\ 1\ 0\ 2\ 1\}\)。
数据范围:
对于第一个测试点,\(|a|,|b| \le 2 \times 10^3\)。
对于第二个测试点,\(|a|,|b| \le 2 \times 10^5\)。
对于 \(100\%\) 的数据,\(1 \le |a|,|b| \le 2 \times 10^7\),所有字符均为小写字母。
首先要分清两个数组,z数组和p数组,首先1+p[i]是z数组对应的那个字符串,i+p[i]是p数组对应的那个数组,而且求p数组的时候要防越界
还有min函数里面第一个数组里面是i-l+1,第二个是r-i+1;
数组的权值计算方式如下:
对于长度为 ( n ) 的数组 ( a ),其权值定义为将每个下标 ( i )(从 ( 1 ) 到 ( n ))对应的值 ( i \times (a_i + 1) ) 进行按位异或(XOR)运算后的结果。具体步骤如下:
- 遍历数组:对每个元素 ( a_i )(( i ) 从 ( 1 ) 到 ( n )),计算 ( i \times (a_i + 1) )。
- 异或运算:将所有计算结果逐个进行异或操作,最终结果即为数组的权值。
数学表达式:
[
\text{权值} = \bigoplus_{i=1}^{n} \left( i \times (a_i + 1) \right)
]
其中,( \bigoplus ) 表示按位异或运算。
示例:
- 当 ( a = [1, 2, 3] ) 且 ( n = 3 ) 时:
- ( i=1 ): ( 1 \times (1+1) = 2 )
- ( i=2 ): ( 2 \times (2+1) = 6 )
- ( i=3 ): ( 3 \times (3+1) = 12 )
- 权值 = ( 2 \oplus 6 \oplus 12 = 8 )。
关键点:
- 异或运算满足交换律和结合律,计算顺序不影响结果。
- 下标 ( i ) 从 ( 1 ) 开始,到 ( n ) 结束。
- 每个项的计算顺序:先计算 ( a_i + 1 ),再乘以 ( i )。
![]()
#include<iostream>
#include<string>
using namespace std;
const int N=2*1e7+5;
long long int p[N];
long long int z[N];
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
string s1,s2;
cin>>s1>>s2;
int n=s1.size();
int m=s2.size();
s1=" "+s1;
s2=" "+s2;
z[1]=m;
for(int i=2,l,r=0;i<=m;i++){
if(i<=r)z[i]=min(z[i-l+1],r-i+1ll);
while(s2[1+z[i]]==s2[i+z[i]])z[i]++;
if(i+z[i]-1>r)l=i,r=i+z[i]-1;
}
for(int i=1,l,r=0;i<=n;i++){
if(i<=r)p[i]=min(z[i-l+1],r-i+1ll);
while(1+p[i]<=m&&i+p[i]<=n&&s2[1+p[i]]==s1[i+p[i]])p[i]++;
if(i+p[i]-1>r)l=i,r=i+p[i]-1;
}
long long int ans1=0,ans2=0;
for(int i=1;i<=m;i++)z[i]=i*(z[i]+1),ans1^=z[i];
for(int i=1;i<=n;i++)p[i]=i*(p[i]+1),ans2^=p[i];
cout<<ans1<<'\n'<<ans2;
return 0;
}


浙公网安备 33010602011771号