首页 > 其他分享 >CF39J Spelling Check 题解

CF39J Spelling Check 题解

时间:2022-08-25 12:01:23浏览次数:59  
标签:set hash 删除 int 题解 哈希 Spelling Check size

很显然,这道题我们只需要快速判断字符串是否相等。

马上想到字符串哈希,哈希算法可以 O(1)O(1) 匹配字符串。

对于字符串哈希,我们先预处理出 basebase 的 kk 次方,不用担心溢出,因为这样更好避免重复。

/*
对于base来说,一般取100上下的质数,常见的有97,131等。
*/
void csh_hash(){
    fi[0]=1;
    for(int i=1;i<=1919810;i++)fi[i]=fi[i-1]*base;
}
struct string_hash{
    int h[N];
    void set(string s){
        int n=s.size();
        for(int i=0;i<n;i++)h[i]=h[i-1]*base+(s[i]-'a'+1);
    }
    int query(int l,int r){return h[r]-h[l-1]*fi[r-l+1];}
}a,b;

现在我们可以完美的匹配两个完整的字符串了。

但是对于删除字母操作,我们要特别注意一下:

struct string_hash{
    int h[N];
    void set(string s){
        int n=s.size();
        for(int i=0;i<n;i++)h[i]=h[i-1]*base+(s[i]-'a'+1);
    }
    int query(int l,int r){return h[r]-h[l-1]*fi[r-l+1];}
    int queryp(int l,int r,int i){return query(l,i-1)*fi[r-i]+query(i+1,r); }
}a,b;

删除操作,我们先查询删除位置前的哈希值,再乘以 base^{r-i}baser−i 得到的值与删除位置后的哈希值相加,就可以得到删除位置 ii 后的哈希值。

为什么?

因为哈希在 set 中已经预处理出了哈希数组 hh ,我们模拟完成段查询的操作:

return h[r]-h[l-1]*fi[r-l+1];

现在只需要删除其中一个点,就把前半段看成一个整体,乘以与后面的位数差即可,删除了 ii 所以要少一位,不用额外加一了。

于是我们可以完美的解出这道题了。

#include<cstdio>
#include<algorithm>
#include<iostream>
#define N 1919810
using namespace std;
int fi[N],ps[N],tot,base=131;
string l,z;
void csh_hash(){
    fi[0]=1;
    for(int i=1;i<=1919810;i++)fi[i]=fi[i-1]*base;
}
struct string_hash{
    int h[N];
    void set(string s){
        int n=s.size();
        for(int i=0;i<n;i++)h[i]=h[i-1]*base+(s[i]-'a'+1);
    }
    int query(int l,int r){return h[r]-h[l-1]*fi[r-l+1];}
    int queryp(int l,int r,int i){return query(l,i-1)*fi[r-i]+query(i+1,r); }
}a,b;
signed main(){
    cin>>l>>z;
    csh_hash();
    a.set(l),b.set(z);
    if(l.size()-1!=z.size())return puts("0"),0;
    int len=l.size(),ll2=z.size();
    for(int i=0;i<len;i++){
        if(a.queryp(0,len-1,i)==b.query(0,ll2-1))ps[++tot]=i+1;
    }
    printf("%d\n",tot);
    for(int i=1;i<=tot;i++)printf("%d ",ps[i]);
    return 0;
}

 

标签:set,hash,删除,int,题解,哈希,Spelling,Check,size
From: https://www.cnblogs.com/masida-hall-LZ/p/16623844.html

相关文章

  • CF51E Pentagon 题解
    这是一道很有趣的图论题。题意简述:给定一个无向图,求五元环的个数,相同元素的环只算一个。假如使用邻接表?枚举五个点?深度过大,最劣的复杂度为 O(m^5)=O(n^{10})O(m5)=O(n......
  • P3755 [CQOI2017]老C的任务 题解
    CDQ分治对于这道题,可以参考 P4390[BOI2007]Mokia摩基亚 的做法,可以通过CDQ分治离线操作高效处理出答案(我常数大,不能体现出CDQ分治的优秀)。可以发现,操作 11......
  • CF1121B Mike and Children 题解
    题意翻译十分简洁,我说几点需要注意的。最多能选几个数?这是错的,要给出最多选出几对数。现在我们就珂以开始了。我的做法理论时间复杂度是 O(n^3)O(n3) 的暴力,但是因......
  • @RequestBody注解转对象中驼峰格式的参数无法接收到数据的问题解决方法
    1.问题:驼峰格式的参数传递到后端,@RequestBody注解标注的实体对象参数没有接收到对应的数据前端传参:执行结果:请求参数实体:importlombok.Data;/***请求参数*@author......
  • CSP 202006-1 202006-2 题解
    #202006-1线性分类器在坐标系中,我们可以考虑使用同一横坐标x值对应的y值来判断在直线的上方一侧还是在下方一侧。当然,如果不在坐标系中也可以统计点和直线的位置关系,这......
  • B3620 题解
    题目传送门\(\color{red}{see}\space\color{green}{in}\space\color{blue}{my}\space\color{purple}{blog}\)小学生又双叒叕来写题解啦!这题是\(x\)进制转\(10\)......
  • CF1646B 题解
    题目传送门\(\color{red}{see}\space\color{green}{in}\space\color{blue}{my}\space\color{purple}{blog}\)看到题解里没有用双指针往中间靠的写法的,果断来一发。思......
  • CF1624C 题解
    题目传送门\(\color{red}{see}\space\color{green}{in}\space\color{blue}{my}\space\color{purple}{blog}\)小学生又双叒叕来写题解啦!这题还是很简单的,甚至不需要像......
  • CF1617B 题解
    题目传送门\(\color{red}{see}\space\color{green}{in}\space\color{blue}{my}\space\color{purple}{blog}\)小学生又双叒叕来写题解啦!其他题解的代码都是\(O(1)\)......
  • CF402A 题解
    题目传送门\(\color{red}{see}\space\color{blue}{in}\space\color{green}{my}\space\color{purple}{blog}\)小学生又双叒叕来写题解啦!看到其他题解描述得并不清晰,我......