codeforces 985F(hash)

首先本题目的意思是给定一个母串,然后每次查询两个长度相等的子串是否同构,同构的定义如下:

For two given strings s and t, say S is the set of distinct characters of s and T is the set of distinct characters of t. The strings s and t are isomorphic if their lengths are equal and there is a one-to-one mapping (bijection) f between S and T for which f(si) = ti. Formally:

  1. f(si) = ti for any index i,
  2. for any character  there is exactly one character  that f(x) = y,
  3. for any character  there is exactly one character  that f(x) = y.

For example, the strings "aababc" and "bbcbcz" are isomorphic. Also the strings "aaaww" and "wwwaa" are isomorphic. The following pairs of strings are not isomorphic: "aab" and "bbb", "test" and "best".

要求对S中某一特定字母,总能找到在T中的某一字母与其字母出现个数相同,且每个出现字母对应的位置相同,


解法:

对26个字母建立26个boolean数组,例如 b[0][1]代表字母a是否在1位置出现,若出现则记为1,没有出现记为0.

这样若两个等长子串同构,则必然对其所在子串的对应到建立的26个数组子串哈希值排序之后对应相等。

(不太会说,觉得难以理解可以留言)

#include
using namespace std;
typedef unsigned long long ull;
const int maxn  = 2e5 + 100;
const int MOD = 1e9+7;
const int N =  27;
int b[N][maxn];
int p[maxn];
int n,m;
char s[maxn];
int get(int id ,int l ,int r){
    return (b[id][r] - (l == 0 ? 0 : b[id][l-1]) + MOD) % MOD;
}
int main()
{
    cin>>n>>m;
    gets(s); gets(s);
    p[0] = 1; for(int i=1;i<=n;i++) p[i] = p[i - 1] * 2 %MOD;
    for(int i=0;i<26;i++)
     for(int j=0;j y) swap(x , y);
         for(int i=0;i<26;i++) xx[i]=1ll * p[y - x] * get(i,x , x + len -1) % MOD,yy[i]=get(i , y, y + len - 1);
         sort(yy , yy + 26) ;
         sort(xx , xx + 26);
         int ok  =1 ;
         for(int i = 0 ;i<26;i++)
         if(xx[i] != yy[i]) {
              ok = 0;
              break;
         }
         printf("%s\n",ok ? "YES":"NO");
    }
    return 0;
}

你可能感兴趣的:(数据结构,codeforces)