CodeForces 985 F Isomorphic Strings

Isomorphic Strings

题意:给你一个长度为n的字符串, m次询问, 每次输入一个s, t, l, 是的 [s,s+l-1] 与 [t,t+l-1] 里面的字符一一对应。并且只能一对一 不能一对多也不能多对一。

题解:Hash求解, 对于这段区间, 找到某个字符对应的字符, 将Hash值转变过去, 最后判断相不相等。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define pb push_back
 5 const LL mod =  (int)1e9+7;
 6 const LL base = 131;
 7 const int N = 2e5 + 100;
 8 char str[N];
 9 int val[N][30];
10 LL Hash[N];
11 int n, m;
12 void init(){
13     Hash[0] = 1;
14     for(int i = 1; i < N; i++)
15         Hash[i] = (Hash[i-1]*base)%mod;
16 }
17 void getHash(){
18     for(int i = 1; i <= n; i++){
19         for(int j = 0; j <= 26; j++)
20             val[i][j] = (val[i-1][j]*base) % mod;
21         int id = str[i] - 'a' + 1;
22         val[i][id] = (val[i][id]+1) % mod;
23         val[i][0] = (val[i][0] + str[i]-'a'+1)%mod;
24     }
25 }
26 LL Get(int id,int l, int r){
27     return ((val[r][id] - val[l-1][id]*Hash[r-l+1]) % mod + mod) % mod;
28 }
29 int vis[27];
30 vector<int> son[27];
31 int main(){
32     scanf("%d%d", &n, &m);
33     scanf("%s", str+1);
34     init();
35     getHash();
36     for(int i = 1; i <= n; i++) son[str[i]-'a'].pb(i);
37     for(int i = 0; i < 26; i++) son[i].pb(n+1);
38     int s, t, l;
39     LL t1, t2;
40     while(m--){
41         memset(vis, 0, sizeof(vis));
42         scanf("%d%d%d", &s, &t, &l);
43         t1 = Get(0,t,t+l-1);
44         t2 = 0;
45         int f = 1;
46         for(int i = 0; i < 26; i++){
47             int pos = *lower_bound(son[i].begin(), son[i].end(), s);
48             if(pos > s+l-1) continue;
49             int tt = str[t+(pos-s)] - 'a';
50             if(vis[tt]) {f = 0; break;}
51             else vis[tt] = 1;
52             t2 += Get(i+1,s,s+l-1) * (tt+1);
53         }
54         t2 %= mod;
55         if(f && t1 == t2) puts("YES");
56         else puts("NO");
57     }
58     return 0;
59 }
985F

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9076939.html