题意:给出一个word字符串和一个page字符串,要求不断重复把p中所有w串删去.
输出最终结果(eg: w=abc p=aaabcbc => ans=a )
题解:经典字符串哈希题目.(下面给出模板)
代码如下:
#include<queue>
#include<set>
#include<map>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
//经典字符串哈希题目
typedef unsigned long long LLU; //若哈希结果超出LL的范围可以自动取模LL_max
const int maxn = 5e6 + 50;
char w[maxn], p[maxn], ans[maxn];
struct Hash
{
LLU has = 99991; //以一个相对较大的质数作为哈希值
LLU has_b[maxn]; //字符串哈希表(用于在母串中p[i]-p[i-len]*has_b[len]时使用,这时得到的才是该子串的哈希值)
LLU w_has; //w串的哈希值
LLU w_len; //w串的长度
LLU p_has[maxn];//p串的哈希值
void init()//初始化
{
w_has = 0; //串哈希值初始化
p_has[0] = 0;
has_b[0] = 1; //哈希表初始化
for (int i = 1; i <= (int)5e6; i++)
has_b[i] = has_b[i - 1] * has;
}
bool check(int pos) //判断子串是否与母串pos开始len长度串匹配成功
{
if (pos >= w_len&&p_has[pos] - p_has[pos - w_len] * has_b[w_len] == w_has)
return true;
return false;
}
void solve()
{
w_len = strlen(w);
for (int i = 0; i < w_len; i++) //获得w串的哈希值
w_has = w_has*has + (w[i] - 'a' + 1);
int top = 0, p_len = strlen(p); //top为ans串的长度
for (int i = 0; i < p_len; i++)
{
ans[top++] = p[i];
p_has[top] = p_has[top - 1] * has + (p[i] - 'a' + 1);
if (check(top)) top -= w_len;
}
for (int i = 0; i < top; i++)
printf("%c", ans[i]);
cout << endl;
}
}H;
int main()
{
while (~scanf("%s%s", &w, &p))
{
H.init();
H.solve();
}
return 0;
}