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;
}
原文地址:https://www.cnblogs.com/luyiming123blog/p/14347352.html