[哈希] hdu 6863 Isomorphic Strings

题目

在这里插入图片描述
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6863

思路

先找出最小的k,k应该是出现过最少次数的单词的因子。
枚举k,然后把k对应的cyclical isomorphic的哈希值存下来,再看看其他长度为k的串的哈希值有没有被存

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<ctime>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<iomanip>
#include<list>
#include<bitset>
#include<sstream>
#include<fstream>
#include<complex>
#include<algorithm>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define int long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int base = 233;
const int mod = 7000061;
int ba[5000100];
int vis[10000010];
string s;
int cnt=0;
bool check(int n,int len){
	cnt++;
	int hx=0;
	for(int i=0;i<len;i++){
		hx=(hx*base+s[i]-'a'+1)%mod;
	}
	vis[hx]=cnt;
	int tmp=s[0]-'a'+1,hxx=0,num=1;
	for(int i=1;i<len;i++){
		hxx=((hx-(tmp*ba[len-1])%mod+mod)%mod*base%mod+tmp)%mod;
		vis[hxx]=cnt;
		hx=hxx;
		tmp=s[num]-'a'+1;
		num++;
	}
	for(int i=1;i<n/len;i++){
		int hxx2=0;
		for(int j=i*len;j<i*len+len;j++){
			hxx2=(hxx2*base+s[j]-'a'+1)%mod;
		}
		if(vis[hxx2]!=cnt) return 0;
	}
	return 1;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	ba[0]=1;
	for(int i=1;i<=5000010;i++) ba[i]=ba[i-1]*base%mod;
	while(t--){
		int n;
		cin>>n;
		cin>>s;
		map<char,int> mp;
		for(int i=0;i<s.size();i++){
			mp[s[i]]++;
		}
		int minn=INF;
		bool flag=0;
		for(char cc='a';cc<='z';cc++){
			if(mp[cc]) minn=min(minn,mp[cc]);
		}
		if(minn==1) cout<<"No"<<endl;
		else{
		for(int i=1;i*i<=minn;i++){
			if(minn%i==0&&n%i==0&&i>1){
				if(check(n,n/i)){
					flag=1;
					break;
				}
			}
			if(minn%i==0&&n%(minn/i)==0&&minn/i!=1&&minn/i!=i){
				if(check(n,n/(minn/i))){
					flag=1;
					break;
				}..
			}
		}
		if(flag) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;}
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值