Z函数16分求调
查看原帖
Z函数16分求调
716965
L_zaa_L楼主2023/11/29 19:23
#include<bits/stdc++.h>
#define int long long
#define For(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define Rof(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define rep(i,  b) for(int i=1,i##end=b;i<=i##end;i++)
using namespace std;
const int N=1e6+9;
const int Mod=998244353;
//char buf[(1<<21)+5],*p1,*p2;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
void chmx(int &x,int y){(x<y)&&(x=y);}
void chmn(int &x,int y){(x>y)&&(x=y);}
inline int read(){
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return f?-x:x;
}
//int lowbit(int x){return x&(-x);}
//int tree[200005];
//void add(int x){for(int i=x;i<=n;i+=lowbit(i)) tree[i]++;}
//int query(int x){
//    int sum=0;
//    for(int i=x;i;i-=lowbit(i)) sum+=tree[i];
//    return sum;
//}
int l,r,ans,z[20000005],p[20000005];
int getZ(int n,char s[]){
	ans=0;l=r=0;z[1]=n;
	for(int i=2;i<=n;i++){
		if(i<=r) z[i]=min(z[i-l+1],r-i+1);
		while(i+z[i]<=n&&s[z[i]+1]==s[i+z[i]])++z[i];
		if(i+z[i]-1>r)l=i,r=i+z[i]-1;
	}
	for(int i=1;i<=n;i++)ans^=(1ll*i*(z[i]+1));
 	return ans;
}
int exkmp(int n,char a[],int m,char b[]){
	ans=0,l=r=0;
	while(p[1]<=min(n,m)&&a[p[1]+1]==b[p[1]+1]) ++p[1];
	for(int i=2;i<=n;i++){ 
		if(i<=r) p[i]=min(z[i-l+1],r-i+1);    
		while(i+p[i]<=n&&b[p[i]+1]==a[i+p[i]])++p[i];             
		if(i+p[i]-1>r)l=i,r=i+p[i]-1;
	}
	for(int i=1;i<=n;i++){
		ans=(ans^(1ll*i*(p[i]+1)));
	}
//	for(int i=1;i<=n;i++) cout<<p[i]<<" ";
	return ans;
}
char a[N],b[N];
signed main(){
	scanf("%s%s",a+1,b+1);
	int n=strlen(a+1),m=strlen(b+1);
	cout<<getZ(m,b)<<endl;
	cout<<exkmp(n,a,m,b);
	return 0;
}

/*
*/
2023/11/29 19:23
加载中...