Scu4438 栈+哈希

题目描述

现在给定一个你很讨厌的字符串 A 和另外一个字符串 B,请删除在 B 中出现的所有 A。
请注意:有可能在删除一个 A 后导致新的 A 出现,此时请继续删除,直到没有 A。

输入格式

输入为多组数据,请处理到 EOF。
对于每组数据:
第一行为你很讨厌的字符串 A,第二行为另外一个字符串 B,均仅包括小写字母。
保证 A串 和 B串 的长度不超过 5000000 且 A、B 均不为空串。

输出格式

对于每组数据,输出一行,即完成删除后的字符串。

样例输入

abc
aaabcbc
b
bbb
abc
ab

样例输出

a

ab

样例解释

第一组数据的删除过程:
aaabcbc -> aa[abc]bc -> aabc -> a[abc] -> a
第二组数据的删除过程:
bbb -> [b]bb -> bb -> [b]b -> b -> [b] ->
第三组数据由于讨厌的字符串并没有出现,所以没有被删除任何一个部分。

思路:开始毫无思路,后来百度他人题解看到了别人的标签,栈,瞬间思路就来了,就像括号匹配一样,这个题目也可以这样做,只是判断是否匹配复杂度很高,这个时候就可以用到哈希,用O(1)的时间判断两个字符串是否匹配,所以总复杂度就是O(n)。

代码:

#include
#define LL long long
#define ULL unsigned long long
#define Max 5000005
const LL mod=1e9+7;
const ULL base=131;
const LL LL_MAX=9223372036854775807;
using namespace std;
ULL Hash[Max],p[Max];
char Stack[Max],a[Max],b[Max];
inline ULL getHashRange(int l,int r){
    return Hash[r]-Hash[l-1]*p[r-l+1];
}
void init(){
    p[0]=1;
    for(int i=1;i=lena){
                ULL t=getHashRange(top-lena+1,top);
                if(t==Hasha){
                    top=max(1,top-lena+1);
                }else
                    top++;
            }
            else
                top++;
        }
        Stack[top]='\0';
        printf("%s\n",Stack+1);
    }

    return 0;
}

你可能感兴趣的:(Acm,哈希,栈)