标签: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 来源: https://www.cnblogs.com/masida-hall-LZ/p/16623844.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。