scu 4438 Censor 字符串哈希+前缀和

传送门:Censor

题目大意

给定一个字符串A和一个字符串B,如果如果B中存在A字符串,就在B中把A字符串去掉,输出最后去掉A字符串之后B字符串

解题思路

这个题目用到了字符串哈希和前缀和的思想!
我们把输入的A字符串哈希为一个整数,然后把用一个数组hb[i]表示B字符串中前i个的哈希值,当i大于字符串A的长度的时候就判断i-lena,i这个区间的哈希值是不是等于A串的。

AC代码

#include<cstdio>
#include<cstring>
const int MAXN = 5e6+5;
const int Hash = 27;
typedef unsigned long long ULL;
char strA[MAXN],strB[MAXN];
char tmp[MAXN];
ULL hb[MAXN];
ULL preHash[MAXN];
void presolve()
{
    preHash[0] = 1;
    for(int i=1;i<MAXN;i++)
        preHash[i] = preHash[i-1]*Hash;
}
int main()
{
    presolve();
    while(~scanf("%s%s",strA,strB))
    {
        int lenA = strlen(strA),lenB = strlen(strB);
        ULL ha=0,top=0;
        if(lenA>lenB){
            printf("%s\n",strB);
            continue;
        }
        hb[0] = 0;
        for(int i=0;i<lenA;i++) ha=ha*Hash + strA[i]-'a'+1;
        for(int i=0;i<lenB;i++){
            tmp[top++] = strB[i];
            hb[top] = hb[top-1]*Hash + strB[i]-'a'+1;
            if(top>=lenA &&hb[top]-hb[top-lenA]*preHash[lenA]==ha) {
                top-=lenA;
            }
        }
        for(int i=0;i<top;i++) printf("%c",tmp[i]);
        puts("");
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值