说在前面
写了几个小时。
题目简述
没有题目简述。
简单口胡
正解是自动机乱搞,但我一看这玩意不能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;
}