清题笔记hdu多校8 1009 Isomorphic Strings

思路

把长度为n的字符串分解成多个同构循环子串,这题是直接暴力求n的因子个数,每个因子看可不可分解,用哈希值存储第一个子串的同构循环子串,进行比较。

这题主要是同构循环子串是怎么设定哈希值的比较烦,直接记下模版吧。
题解代码来源

#include<bits/stdc++.h>
#define ll long long
using namespace std;
using namespace std;
const int mod=1e7+7;
const int base=1331;
const int N=5e6+10;
int T;
int n;
char s[N];
int p[N],a[N];
int jl[mod];
int js(int l,int r) { // 子串哈希值
 return (a[r]-1ll*a[l-1]*p[r-l+1]%mod+mod)%mod;
}
int tot=0; //时间戳
bool pd(int k,int id) {
 if(k==1) return 0;
 int len=n/k;
 int l=1,r=len;
 jl[js(1,len)]=id;
 for(int i=1;i<len;i++) {
 	int temp1=(1ll*js(i+1,len)*p[i]%mod+js(1,i))%mod;
 	jl[temp1]=id;//将循环同构子串标记为相同 
 }
//	printf("len=%d\n",len);
 for(int i=1;i<=k;i++) {
 	int temp=js(l,r);
 //	printf("temp=%d,jl=%d\n",temp,jl[temp]);
 	if(jl[temp]!=id) return 0; // 不是子集
 	l+=len,r+=len;
 }
 return 1;
}
int main()
{
 //cwk;
 scanf("%d",&T);
 p[0]=1;
 for(int i=1;i<N;i++) p[i]=(1ll*p[i-1]*base)%mod;
 while(T--) {
 	scanf("%d",&n);
 	scanf("%s",s+1);
 	for(int i=1;i<=n;i++) {
 		a[i]=(1ll*a[i-1]*base%mod+(s[i]-'a'+1))%mod;
 	}
 	int flag=0;
 	for(int i=1;1ll*i*i<=1ll*n&&!flag;i++) { // 根号枚举因数
 		if(n%i==0) {
 			flag|=pd(i,++tot);
 			flag|=pd(n/i,++tot);
 		}
 	}
 	if(!flag) puts("No");
 	else puts("Yes");
 }

 return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值