题目链接:点击进入
题目
题意
给长度为n的字符串,查询m次,每次查询 s [ x ] ~ s [ x + l - 1 ] 的子串与 s [ y ] ~ s [ y + l - 1 ] 的子串是不是同构的
(例如 “aababc” and “bbcbcz” 就是同构的,“aab” and “bbb” 就不是)
思路
拿"aababc" and “bbcbcz” 来说,将两个字符串转换为 x 进制的表示方式
“aababc”: a x 5 + a x 4 + b x 3 + a x 2 + b x 1 + c x 0 = a ( x 5 + x 4 + x 2 ) + b ( x 3 + x 1 ) + c ( x 0 ) ax^5+ax^4+bx^3+ax^2+bx^1+cx^0=a(x^5+x^4+x^2)+b(x^3+x^1)+c(x^0) ax5+ax4+bx3+ax2+bx1+cx0=a(x5+x4+x2)+b(x3+x1)+c(x0)
“bbcbcz”: b x 5 + b x 4 + c x 3 + b x 2 + c x 1 + z x 0 = b ( x 5 + x 4 + x 2 ) + c ( x 3 + x 1 ) + z ( x 0 ) bx^5+bx^4+cx^3+bx^2+cx^1+zx^0=b(x^5+x^4+x^2)+c(x^3+x^1)+z(x^0) bx5+bx4+cx3+bx2+cx1+zx0=b(x5+x4+x2)+c(x3+x1)+z(x0)
两者的特点就是都是由
(
x
5
+
x
4
+
x
2
)
+
(
x
3
+
x
1
)
+
(
x
0
)
(x^5+x^4+x^2)+(x^3+x^1)+(x^0)
(x5+x4+x2)+(x3+x1)+(x0)组成,唯一区别就是前面的系数,也就是字母不同,但若是系数等于 1 ,两者就相同了。因此,我们可以对每一个字母求字符串哈希值。
对于每次询问,将 26 个字母在子串中的哈希值存起来,若是两个子串排序后的序列一样,说明两个子串同构,否则不同构。
代码
// Problem: Isomorphic Strings
// Contest: Virtual Judge - CodeForces
// URL: https://vjudge.net/problem/CodeForces-985F
// Memory Limit: 262 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
//#pragma GCC optimize(3)//O3
//#pragma GCC optimize(2)//O2
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define base 233
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define lowbit(x) x & -x
#define inf 0x3f3f3f3f
//#define int long long
//#define double long double
//#define rep(i,x,y) for(register int i = x; i <= y;++i)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const int maxn=1e6+10;
const int mod=1e9+7;
const double eps=1e-9;
const int N=5e3+10;
/*--------------------------------------------*/
inline int read()
{
int k = 0, f = 1 ;
char c = getchar() ;
while(!isdigit(c)){if(c == '-') f = -1 ;c = getchar() ;}
while(isdigit(c)) k = (k << 1) + (k << 3) + c - 48 ,c = getchar() ;
return k * f ;
}
/*--------------------------------------------*/
int n,m;
ll p[maxn],h[26][maxn];
string s;
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
cin>>n>>m;
p[0]=1;
for(int i=1;i<=n;i++)
p[i]=(p[i-1]*base)%mod;
cin>>s;
for(int i=0;i<26;i++)
for(int j=1;j<=n;j++)
h[i][j]=(h[i][j-1]*base+((s[j-1]-'a')==i))%mod;
while(m--)
{
int x,y,l;
cin>>x>>y>>l;
vector<int>v1;
vector<int>v2;
for(int i=0;i<26;i++)
{
v1.push_back(((h[i][x+l-1]-h[i][x-1]*p[l])%mod+mod)%mod);
v2.push_back(((h[i][y+l-1]-h[i][y-1]*p[l])%mod+mod)%mod);
}
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
if(v1==v2) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}