F - Censor SCU - 4438(栈 + hash)

分析

  • 题意
  1. 给我们一个字符串 t,又给我们一个字符串s,让我们删除 s中第一个的t,如果在删除之后的s字符串还存在t那么我们一直删除,直到删除之后不在 出现t为止,输出s剩余的内容

样例

abc
aaabcbc
  • 思路
  1. 这题的巧妙之处是使用了栈的特性(括号匹配题型),而Hash的作用是通过将子串转化为 hash值,同判断hash值相同,我们就将相同的这个子串从 栈 中弹出,然后继续往里面添加字符串,继续进行 相同字符串的匹配(这个匹配类似于 括号匹配题型)
  2. 过程模拟,我们假设有一个 栈st,当我把 s中的前四个字符 a、a、a、b 依次压入st中的时候,我们判读 栈顶的前3个字符仍然不等于abc,
  3. 当我们压入 s中的 第5个字符串的时候,此时 st 顶部的前三个单词为 a、b、c,整好和 t 字符串相同,此时我们把 st的前三个字符 弹出,
  4. 之后 我们再次把s中的第 6、7个字符压入st中,此时 st 顶部的前三个单词为 a、b、c,整好和 t 字符串相同,此时我们把 st的前三个字符 弹出,
  5. 这样栈中剩下的字符就是,就是ans,
  6. 注意我们 在判断字符串相同的时候 用的是 hash

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define db double
#define Pir pair
#define m_p make_pair
#define INF 0x3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
#define for_(i, s, e) for(int i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(int i = (ll)(e); i >= (ll)(s); i --)
#define sc scanf
#define pr printf
#define sd(a) scanf("%d", &a)
#define ss(a) scanf("%s", a)
using namespace std;

const int mxn = 5e6 + 10;
ull bsc = 131; 
ull bse[mxn];
ull has[mxn];

void init()
{
    bse[0] = 1;
    for_(i, 1, mxn - 1) bse[i] = bse[i - 1] * bsc;
}

ull Hash(char s[])
{
    int n = strlen(s + 1);
    ull hs = 0;
    for_(i, 1, n) hs = hs * bsc + s[i];
    return hs;
}

ull get_has(int l, int r)
{
    return has[r] - has[l] * bse[r - l];
}

char s[mxn], t[mxn], ans[mxn];

int main()
{
    /* fre(); */
    init();
    while(~ sc("%s %s", s + 1, t + 1))
    {
        int n = strlen(s + 1); 
        int m = strlen(t + 1);
        ull hs = Hash(s);
        int tp = 0;

        for_(i, 1, m)
        {
            ans[++ tp] = t[i];
            has[tp] = has[tp - 1] * bsc + t[i];
            if(tp >= n && get_has(tp - n, tp) == hs)
                tp -= n;
        }

        ans[tp + 1] = '\0';
        pr("%s\n", ans + 1);
    }


    return 0;
}

你可能感兴趣的:(#Hash)