P3121 [USACO15FEB]Censoring G(AC自动机+STL)

传送门
洛谷的标签和题解都说这题需要用栈,但其实用一个记忆数组pre+string类的earse函数就够了.只需要每次跑到可以删除的状态,直接删然后跑回pre[i-len]就可以了.
代码

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 4e5+10;

inline int read(){
    
    
    int x = 0,f=1;char ch = getchar();
    while(ch<'0'||ch>'9'){
    
    if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){
    
    x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

namespace Auto{
    
    
    int trie[26][N],fail[N],fa[N],tot,dep[N],p,ed[N],tt[26][N],pre[N];
    vector<pii> vec;
    void ins(string s){
    
    
        p = 0;
        int dp = 1;
        for(auto x:s){
    
    
            int ch = x - 'a';
            if(!trie[ch][p]) fa[++tot] = p,dep[tot] = dp,trie[ch][p] = tot,tt[ch][p] = tot;
            p = trie[ch][p];
            dp++;
        }
        ed[p] = 1;
    }
    void bfs(){
    
    
        queue<int> q;
        fir(i,0,25) if(trie[i][0]) q.push(trie[i][0]);
        while(q.size()){
    
    
            int p = q.front();q.pop();
            fir(i,0,25){
    
    
                int fl = fail[p];
                if(trie[i][p]) fail[trie[i][p]] = trie[i][fl],q.push(trie[i][p]);
                else trie[i][p] = trie[i][fl];
            }
        }
    }
    void dfs(string &s){
    
    
        p = 0;
        fir(i,0,(int)s.size()-1){
    
    
            char x = s[i];
            int ch = x - 'a';
            p = trie[ch][p];
            if(ed[p]){
    
    
                int len = dep[p];
                s.erase(i-len+1,len);
                p = pre[i-len];
                i = i-len;
                pre[i] = p;
                continue;
            }
            pre[i] = p;
        }
    }
}
using namespace Auto;
int main(){
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    string str,s;
    cin >> str; 
    int n;
    cin >> n;
    fir(i,1,n){
    
    
        cin >> s;
        ins(s);
    }
    bfs();
    dfs(str);
    cout << str << "\n";
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45590210/article/details/109814455