题目链接
https://codeforces.com/contest/985/problem/F
题意
首先定义两个长度相等字符串a,b同构,当且仅当a中的每个字母,b中只存在一个字母与之对应,并且两个字母出现位置要完全一致,a,b反过来也要满足。
给定一个长度为\(2 \times 10^5\)的字符串s,有很多次询问。每次询问s从x位置开始的长度为l的字串与从y开始的长度为l的字串是否同构。
分析
对每个字母出现位置的集合进行哈希。
比如对于字母\(‘k‘\),我们把原串中出现\(‘k‘\)的位置用1替代,其他用0替代。求出新产生的01串的哈希,这样01串某个字串的哈希其实就代表着\(‘k‘\)在这个字串中出现位置的集合。
(据说自然溢出会wa)
代码
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=200050;
const ll MOD=1e9+7;
ll h[26][maxn],x=107,px[maxn];
char s[maxn];
int main(){
int n,m;
scanf("%d%d", &n,&m);
scanf("%s", s+1);
px[0]=1;
for(int i = 1; i <= n; ++i) px[i]=px[i-1]*x%MOD;
for(int i = 0; i < 26; ++i){
for(int j = 1; j <= n; ++j){
h[i][j]=(h[i][j-1]*x+int(s[j]==i+‘a‘))%MOD;
}
}
while(m--){
int x,y,l;
scanf("%d%d%d", &x,&y,&l);
vector<int> p,q;
for(int i = 0; i < 26; ++i){
p.push_back(((h[i][x+l-1]-px[l]*h[i][x-1]%MOD)%MOD+MOD)%MOD);
q.push_back(((h[i][y+l-1]-px[l]*h[i][y-1]%MOD)%MOD+MOD)%MOD);
}
sort(q.begin(),q.end());
sort(p.begin(),p.end());
printf("%s\n", p==q?"YES":"NO");
}
return 0;
}
原文地址:https://www.cnblogs.com/sciorz/p/9092648.html
时间: 2024-11-09 03:20:48