• NOIP模拟 string


    题目大意:

    给n个字符串(100位以内),和一个长串s(100000位以内),求n个字符串在s中出现的次数。然后给出m次修改,每次修改s中的一个字符,对于每次修改,输出更新后的答案(修改会保存)。

    题目分析:

    没有修改就是ac自动机裸题。虽然带了修改,但发现匹配的字符串最多才100位,也就是说每次修改的pos位置的字符最多影响[pos-l,pos+l]这个区间的答案,于是便有了正解:每次修改前,将该区间的答案减掉,在加上修改后该区间的答案。

    code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<queue>
    #include<cmath>
    using namespace std;
    
    struct node{
        int trans[30], fail, cnt;
        inline void init(){
            memset(trans, 0, sizeof trans);
            fail = cnt = 0;
        }
    }tr[1000005];
    int tot = 0;
    
    inline void insert(string &s){
        int pos = 0;
        for(int i = 0; i < s.length(); i++){
            if(!tr[pos].trans[s[i] - 'a' + 1]) tr[tr[pos].trans[s[i] - 'a' + 1] = ++tot].init();
            pos = tr[pos].trans[s[i] - 'a' + 1];
        }
        tr[pos].cnt++;
    }
    
    inline void build_fail(){
        queue<int> que;
        que.push(0);
        while(!que.empty()){
            int u = que.front(); que.pop();
            tr[u].cnt += tr[tr[u].fail].cnt;
            for(int i = 1; i <= 26; i++){
                if(tr[u].trans[i]){
                    que.push(tr[u].trans[i]);
                    if(u) tr[tr[u].trans[i]].fail = tr[tr[u].fail].trans[i];
                }
                else tr[u].trans[i] = tr[tr[u].fail].trans[i];
            }
        }
    }
    
    string t;
    inline int ac(int l, int r){
        int ans = 0, pos = 0;
        for(int i = l; i <= r; i++){
            pos = tr[pos].trans[t[i] - 'a' + 1];
            ans += tr[pos].cnt;
        }
        return ans;
    }
    
    int maxl;
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(NULL), cout.tie(NULL);
        int n, q; cin >> n >> q;
        for(int i = 1; i <= n; i++){
            string s;
            cin >> s;
            insert(s); int len = s.length();
            maxl = max(maxl, len);
        }
        build_fail();
        cin >> t;
        int ans; 
        int len = t.length();
        cout << (ans = ac(0, len - 1)) << endl;
        for(int i = 1; i <= q; i++){
            int pos; char c; cin >> pos >> c; pos--;
           
            ans -= ac(max(0, pos - maxl), min(len - 1, pos + maxl));
            t[pos] = c;
            ans += ac(max(0, pos - maxl), min(len - 1, pos + maxl));
            cout << ans << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    Deadlock Detecting--转
    java.util.concurrent包详细分析--转
    spring源码分析之spring-core总结篇
    Google和Baidu常用的搜索技巧--转
    极速发展的饿了么订单系统架构演进--转
    唯品会订单分库分表的实践总结以及关键步骤--转
    数据扩展性探讨和总结--转
    MAT使用--转
    Java 8 Stream API详解--转
    论海明威的存在主义宗教意识——存在主义虚无主义。注:部分观点个人不赞同
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7683579.html
Copyright © 2020-2023  润新知