Fork me on GitHub

Codeforces 985F-Isomorphic Strings

Codeforces 985F-Isomorphic Strings

题意

给定一个字符串\(s\),长为\(n\)\(m\)组询问,每次询问给出\(x\)\(y\)\(len\),问是否存在一一映射,使得\(s\)中起点为\(x\)长度为\(len\)的子串能映射成起点为\(y\),长度为\(len\)的子串。

题解

是否存在映射取决于字母的排列情况是否一致。我们可以以26个字母分别为关键字将整个字符串\(s\)表示成一个0,1串(如字符串“aabcc”,以a为关键字“11000”,b为关键字“00100”,c为关键字“00011”,其余字母为关键字均为“00000”),那么,如果两个字串相等,他们26个0,1串排好序后就应该一致。我们可以用hash来比较0,1串是否一致。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=2e5+10;
const int base=131;
const ll mod=1e9+7;
char s[N];
ll h[30][N];
ll sum[N];
ll a[30],b[30];
int len,n,t;

void Hash(){
	for(int i=0;i<26;i++){
		for(int j=1;j<=len;j++){
			ll x;
			if(s[j]=='a'+i) x=1;
			else x=0;
			h[i][j]=(h[i][j-1]*base%mod+x)%mod;
		}
	}
}

void init(){
	sum[0]=1;
	for(int i=1;i<=len;i++){
		sum[i]=(sum[i-1]*base)%mod;
	} 
}

bool solve(int l,int r,int d){
	for(int i=0;i<26;i++){
		a[i]=(h[i][l+d-1]-h[i][l-1]*sum[d]%mod+mod)%mod;
		b[i]=(h[i][r+d-1]-h[i][r-1]*sum[d]%mod+mod)%mod;
	}
	sort(a,a+26);sort(b,b+26);
	for(int i=0;i<26;i++){
		if(a[i]!=b[i]) return 0;
	}
	return 1;
}


int main(){
	scanf("%d%d",&n,&t);
	scanf("%s",s+1);
	len=strlen(s+1);
	Hash();
	init();
	for(int i=1;i<=t;i++){
		int l,r,d;
		scanf("%d%d%d",&l,&r,&d);
		if(solve(l,r,d)) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
} 
posted @ 2020-03-15 16:03  qjy_73  阅读(196)  评论(0)    收藏  举报