zoukankan      html  css  js  c++  java
  • [bzoj3940][Usaco2015 Feb]Censoring

    最近做题成双成对?不是双倍经验就是两题同解。

    3940    3942

    给定字典,给定字符串,删去字符串中所有字典内单词。保证不会出现二者包含状况。$n leq 1e5,sum len leq 1e5$

    AC自动机裸题。build出AC自动机后从左到右插入文本串,同时边匹配边push进栈里。匹配成功就弹栈。

    注意要记录匹配到第几个字符的时候,AC自动机指针(我管那个一直蹦的东西就叫指针了?)指到哪里。弹栈之后要指针也要跳回来。

    #include<bits/stdc++.h>
    #define x first
    #define y second
    using namespace std;
    typedef pair<int,int> P;
    const int N=100010;
    struct ACAM{
        int ch[N][26],cnt[N],f[N];
        int sz,rt;
        void init(){
            memset(ch,-1,sizeof ch);
            memset(cnt,0,sizeof cnt);
            memset(f,0,sizeof f);
            sz=rt=0;
        }
        void ins(char *s){
            int n=strlen(s),u=rt;
            for(int i=0;i<n;i++){
                int c=s[i]-'a';
                if(!~ch[u][c])
                ch[u][c]=++sz;
                u=ch[u][c];
            }
            cnt[u]=n;
        }
        void build(){
            queue<int>q;
            while(!q.empty())q.pop();
            for(int i=0;i<26;i++)
            if(~ch[rt][i])
            f[ch[rt][i]]=rt,q.push(ch[rt][i]);
            else ch[rt][i]=rt;
            while(!q.empty()){
                int u=q.front();q.pop();
                for(int i=0;i<26;i++){
                    int v=ch[u][i];
                    if(~v){
                        int now=f[u];
                        while(f&&!~ch[now][i])now=f[now];
                        f[v]=ch[now][i];q.push(v);
                    }
                    else ch[u][i]=ch[f[u]][i];
                }
            }
        }
        void query(char *s){
            int n=strlen(s);
            stack<P>S;int u=0;
            while(!S.empty())S.pop();
            for(int i=0;i<n;i++){
                int c=s[i]-'a';
                while(u&&!~ch[u][c])u=f[u];
                u=ch[u][c];S.push(P(c,u));
                if(cnt[u]){
                    for(int j=1;j<=cnt[u];j++)
                    S.pop();
                    if(!S.empty())u=S.top().y;
                    else u=0;
                }
            }
            vector<char>ans;
            while(!S.empty())
            ans.push_back(S.top().x+'a'),S.pop();
            for(int i=ans.size()-1;~i;i--)
            printf("%c",ans[i]);
        }
    }Aho;
    char str[N],s[N];
    int main(){
        scanf("%s",str);
        int n;scanf("%d",&n);
        Aho.init();
        for(int i=1;i<=n;i++){
            memset(s,0,sizeof s);
            scanf("%s",s);
            Aho.ins(s);
        }
        Aho.build();
        Aho.query(str);
    }
  • 相关阅读:
    ISP整体流程介绍
    Demosiac 去马赛克 (CIP)
    ISP-CMOS图像传感器内部结构及工作原理
    数字图像显示原理
    浅析图像到视频
    摄像机gamma校正
    理解 Pix Binning
    人工智能"眼睛"——摄像头
    CMOS 摄像头的Skipping 和 Binning 模式
    android 向服务器发送json数据,以及发送头信息的三种方式
  • 原文地址:https://www.cnblogs.com/orzzz/p/8094213.html
Copyright © 2011-2022 走看看