codeforces 985 F. Isomorphic Strings


题目链接

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-08-28 23:21:13

codeforces 985 F. Isomorphic Strings的相关文章

【Codeforces 985 F】Isomorphic Strings

题意:给一个字符串\(s\),有\(q\)个询问 x y l 表示问从\(x,y\)开始的长度为\(l\)的子串是否等价. 等价的定义是是否可以形成一个映射\(f\),使得把所有的第一个字符串的字符经过映射后得到恰恰是第二个字符串. 思路:首先我们看如果一个字符串等价于另一个字符串,那么它们所有字符出现位置的哈希值可以一一对应. 那么我们可以处理前缀每个字符出现的哈希值. 那么我们就可以\(O(26)\)求出每次查询了. 一一对应很简单,就是排序之后相同就行了. 原文地址:https://www

LeetCode:Isomorphic Strings

1.题目名称 Isomorphic Strings(同构的字符串) 2.题目地址 https://leetcode.com/problems/isomorphic-strings/ 3.题目内容 英文: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurre

Codeforces 360C Levko and Strings dp

题目链接:点击打开链接 题意: 给定长度为n的字符串s,常数k 显然s的子串一共有 n(n-1)/2 个 要求找到一个长度为n的字符串t,使得t对应位置的k个子串字典序>s #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<vector> #include<set> using namespace std; #

[2016-03-23][codeforces][560][D][Equivalent Strings]

时间:2016-03-23 14:15:39 星期三 题目编号:[2016-03-23][codeforces][560][D][Equivalent Strings] 题目大意:定义两个字符串相等方式,给出两个字符串,问是否相等 分析:递归判断即可 遇到的问题:长度为奇数的字符串一定不相等 #include <iostream> #include <string> using namespace std; int issame(string str1,string str2){

Codeforces 385B Bear and Strings

题目链接:Codeforces 385B Bear and Strings 记录下每一个bear的起始位置和终止位置,然后扫一遍记录下来的结构体数组,过程中用一个变量记录上一个扫过的位置,用来去重. #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAX_N = 5000 + 100; char str[MAX_N]; struct Node

Codeforces 727 F. Polycarp&#39;s problems

Description 有一个长度为 \(n\) 有正负权值的序列,你一开始有一个值,每次到一个权值就加上,最少需要删掉多少数值才能到序列末尾.\(n \leqslant 750,m \leqslant 2 \times 10^5\) Sol DP+二分. 发现这个东西有后效性,就是前面选不选会影响后面的决策,并且权值太大无法记录. 但是我们可以倒着做,因为后面的决策无法影响前面的决策. \(f[i][j]\) 表示到 \(i\) 删掉 \(j\) 个至少需要的初始权值. 因为初始权值非负,所以

Codeforces 482C Game with Strings(dp+概率)

题目链接:Codeforces 482C Game with Strings 题目大意:给定N个字符串,现在从中选定一个字符串为答案串,你不知道答案串是哪个,但是可以通过询问来确定, 每次询问一个位置上字符为多少.现在你询问的每个位置的概率是相同的,(问过的位置不会再问),求询问次数的期 望. 解题思路:因为字符串长度不会大于20,所以用二进制表示询问了哪些位置,C[s]即为询问s的位置可以确定多少个字 符串.这步不能通过枚举s,然后判断处理,复杂度为o(2^20 * 20 * 50),太高.可

leetcode_205题——Isomorphic Strings(用的map)

Isomorphic Strings Total Accepted: 5891 Total Submissions: 24698My Submissions Question Solution Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences

leetcode 204/187/205 Count Primes/Repeated DNA Sequences/Isomorphic Strings

一:leetcode 204 Count Primes 题目: Description: Count the number of prime numbers less than a non-negative number, n 分析:此题的算法源码可以参看这里,http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 代码: class Solution { public: int countPrimes(int n) { // 求小于一个数n的素数个