• CF710F String Set Queries


    说在前面

    写了几个小时。

    题目简述

    没有题目简述。

    简单口胡

    正解是自动机乱搞,但我一看这玩意不能Trie做嘛?哦,内存不够,诶KMP也可以,啊复杂度有点高。

    然后以(1000)为分界线,长度大于(1000)的用KMP,小于(1000)的用Trie树,噫,好,开始写!


    Four hours Later
    awsl,写完了

    # include <bits/stdc++.h>
    using namespace std;
    const int N = 3e5 + 5;
    # define int long long
    int n;
    char s[N]; 
    
    const int L = 10000;
    
    char S[600][N];
    
    int cur = 0;
    int flag[N];
    
    template <typename T> void read(T &x)
    {
        int w = 1;
        x = 0;
        char ch = getchar();
        while(!isdigit(ch))
        {
            if(ch == '-') w = -1;
            ch = getchar();
        }
        while(isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        x *= w;
        return;
    }
    
    template <typename T> void write(T x)
    {
        if(x < 0) putchar('-'),x = -x;
        if(x > 9) write(x / 10);
        char ch = (x % 10) + 48;
        putchar(ch);
    }
    
    struct _Trie
    {
        int T[N][26];
        int tot = 0;
        int cnt[N];
        void insert(char* s,int delta)
        {
            int len = strlen(s);
            int root = 0;
            for(int i = 0; i < len; i++)
            {
                if(T[root][s[i] - 'a'] == 0) T[root][s[i] - 'a'] = ++tot;
                root = T[root][s[i] - 'a'];
            }
            cnt[root] += delta;
            return;
        }
    }Trie;
    
    struct _KMP{
        int Next[N];
        void getNext(char* s){
            memset(Next,0,sizeof(Next));
            int i=0,j=-1;Next[0]=-1;
            int len = strlen(s);
            while(i<len)
            {
                if(j==-1||s[i]==s[j]){
                    ++i;++j;
                    Next[i]=j;
                }
                else j=Next[j];
            }
        }
        int Match(char* str,char *s)
        {
            int sum=0,j=0,lens=strlen(s),lenstr=strlen(str);
            getNext(s);
            for(int i=0;i<lenstr;i++)
            {
                while(j>0&&s[j]!=str[i])
                {
                    j=Next[j];
                }
                if(s[j]==str[i])
                    j++;
                if(j==lens)
                {
                    sum++;j=Next[j];
                }
            }
            return sum;
        }
    }KMP;
    
    signed main(void)
    {
        // freopen("In.in","r",stdin);
        read(n);
        bool Flag = (n == 2);
        // cout << n << endl;
        cur = 0;
        while(n--)
        {
            int len;
            int opt;
            read(opt);
            scanf("%s",s);
            // cur = 0;
            len = strlen(s);
            if(opt == 1)
            {
                if(len <= L) 
                {
                    // if(Flag && s[0] =='a' && s[1] == 'a' && s[2] == 'a' && s[3] == 'a') cout << "YES1
    ";
                    Trie.insert(s,1);
                }
                else 
                {
                    ++cur;
                    for(int i = 0; i < len; i++) S[cur][i] = s[i];
                    // printf("s = %s
    ",s);
                    flag[cur] = 1; // 1 add 0 delete
                }
            }
            else
            {
                if(opt == 2)
                {
                    if(len <= L) 
                    {
                        Trie.insert(s,-1);
                    }
                    else
                    {
                        ++cur;
                        for(int i = 0; i < len; i++) S[cur][i] = s[i];
                        flag[cur] = -1;
                    }
                }
                else
                {
                    int ans = 0;
                    int root = 0;
                    for(int i = 0; i < len; i++)
                    {
                        root = 0;
                        for(int j = i; j < len; j++)
                        {
                            if(Trie.T[root][s[j] - 'a'] == 0) break;
                            root = Trie.T[root][s[j] - 'a'];
                            ans += Trie.cnt[root];
                        }
                    }
                    for(int i = 1; i <= cur; i++)
                    {
                        // cout << s << " " << S[i] << " Match = " << KMP.Match(s,S[i]) << endl;
                        if(strlen(S[i]) <= len) ans = ans + (KMP.Match(s,S[i]) * flag[i]);
                    }
                    // if(Flag) ans = 193492;
                    write(ans);
                    putchar('
    ');
                    fflush(stdout);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    JS中return函数
    Java异常
    ssh框架整合之注解版
    ssh框架整合之xml版
    Struts之拦截器
    Struts入门初体验
    Hibernate关联查询 一对多双向关联
    Hibernate之hql
    Aop小列子
    深入.Net第二章总结
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/14347352.html
Copyright © 2020-2023  润新知