nn个事件,每次给出SS

  1. 在当前字符串集中加入SS
  2. 在当前字符串集中删去SS
  3. 查询最早在哪个事件之后,SS为前缀的字符串数量超过了vv

强制在线

n105,S60n\le 10^5, |S|\le 60

LOJ2291

Solution

一开始还以为要二分答案,后面发现直接在Trie上模拟,对于每个节点维护一个vector暴力记录答案即可

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <bits/stdc++.h>

#define x first
#define y second
#define y1 Y1
#define y2 Y2
#define mp make_pair
#define pb push_back

using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

template <typename T> inline int Chkmax (T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline int Chkmin (T &a, T b) { return a > b ? a = b, 1 : 0; }
template <typename T> T read ()
{
T sum = 0, fl = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fl = -1;
for (; isdigit(ch); ch = getchar()) sum = (sum << 3) + (sum << 1) + ch - '0';
return sum * fl;
}

inline void proc_status()
{
ifstream t ("/proc/self/status");
cerr << string (istreambuf_iterator <char> (t), istreambuf_iterator <char> ()) <<endl;
}

const int Maxn = 1e5 + 100;

int N, M;

int node_cnt = 1;
struct info
{
int ch[27], cnt;
vector <int> p;
}node[Maxn * 40];

struct TRIE
{

inline void insert (char *S, int op, int id)
{
int n = strlen(S), now= 1;
for (int i = 0; i < n; ++i)
{
int x = S[i] - 'a';
if (!node[now].ch[x]) node[now].ch[x] = ++node_cnt;
now = node[now].ch[x];
node[now].cnt += op;
if (node[now].cnt > node[now].p.size()) node[now].p.pb(id);
}
}

inline int query (char *S, int times)
{
int n = strlen(S), now = 1;
for (int i = 0; i < n; ++i) now = node[now].ch[S[i] - 'a'];
if (!now || node[now].p.size() <= times) return -1;
return node[now].p[times];
}

} T;

inline void Solve ()
{
int ans = 0;
for (int id = 1; id <= M; ++id)
{
int op = read<int>();
char S[100]; scanf("%s", S);

if (op <= 2) T.insert(S, op == 1 ? 1 : -1, id);
else
{
int a = read<int>(), b = read<int>(), c = read<int>();
int sum = ((LL)a * abs(ans) + b) % c;
ans = T.query (S, sum);
printf("%d\n", ans);
}
}
}

inline void Input ()
{
M = read<int>();
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("A.in", "r", stdin);
freopen("A.out", "w", stdout);
#endif
Input();
Solve();
return 0;
}