Skip to content

Commit 1111189

Browse files
2019.10.28 at school
1 parent d4cdd39 commit 1111189

File tree

2 files changed

+180
-1
lines changed

2 files changed

+180
-1
lines changed

part2/cf587F.cpp

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#include <cstdio>
2+
#include <cstring>
3+
#include <cstdlib>
4+
#include <cmath>
5+
#include <ctime>
6+
#include <cctype>
7+
8+
#include <algorithm>
9+
#include <tuple>
10+
#include <random>
11+
#include <bitset>
12+
#include <queue>
13+
#include <functional>
14+
#include <set>
15+
#include <map>
16+
#include <vector>
17+
#include <chrono>
18+
#include <iostream>
19+
#include <limits>
20+
#include <numeric>
21+
22+
#define LOG(FMT...) fprintf(stderr, FMT)
23+
24+
using namespace std;
25+
26+
typedef long long ll;
27+
typedef unsigned long long ull;
28+
29+
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
30+
31+
template <class T>
32+
istream& operator>>(istream& is, vector<T>& v) {
33+
for (T& x : v)
34+
is >> x;
35+
return is;
36+
}
37+
38+
template <class T>
39+
ostream& operator<<(ostream& os, const vector<T>& v) {
40+
if (!v.empty()) {
41+
os << v.front();
42+
for (int i = 1; i < v.size(); ++i)
43+
os << ' ' << v[i];
44+
}
45+
return os;
46+
}
47+
48+
const int N = 101010, B = 323;
49+
50+
int n, m, tot, b, vc;
51+
int vertex[N], len[N];
52+
int trie[N][26], fail[N], prt[N], dfn[N], dfnr[N];
53+
vector<pair<int, int>> qry1[N], qry2[N];
54+
char s[N];
55+
ll ans[N];
56+
vector<int> ch[N];
57+
58+
int inb[N], blk[B];
59+
60+
int sub[N];
61+
ll pre[N];
62+
63+
void dfs(int u) {
64+
static int t;
65+
dfn[u] = ++t;
66+
for (int v : ch[u])
67+
dfs(v);
68+
dfnr[u] = t;
69+
}
70+
71+
void dfs2(int u) {
72+
for (int v : ch[u]) {
73+
dfs2(v);
74+
sub[u] += sub[v];
75+
}
76+
}
77+
78+
void change(int k, int x) {
79+
for (; k % b != 0; ++k)
80+
inb[k] += x;
81+
k /= b;
82+
for (; k <= b; ++k)
83+
blk[k] += x;
84+
}
85+
86+
int query(int k) {
87+
return inb[k] + blk[k / b];
88+
}
89+
90+
int main() {
91+
ios::sync_with_stdio(false);
92+
cin.tie(nullptr);
93+
94+
cin >> n >> m;
95+
int rt = ++vc;
96+
for (int i = 1; i <= n; ++i) {
97+
cin >> (s + 1);
98+
len[i] = strlen(s + 1);
99+
tot += len[i];
100+
int v = rt;
101+
for (int j = 1; j <= len[i]; ++j) {
102+
if (!trie[v][s[j] - 'a']) {
103+
trie[v][s[j] - 'a'] = ++vc;
104+
prt[vc] = v;
105+
}
106+
v = trie[v][s[j] - 'a'];
107+
}
108+
vertex[i] = v;
109+
memset(s + 1, 0, len[i]);
110+
}
111+
b = sqrt(tot) + 1;
112+
for (int i = 1; i <= m; ++i) {
113+
int l, r, k;
114+
cin >> l >> r >> k;
115+
if (len[k] >= b) {
116+
qry2[k].emplace_back(l - 1, -i);
117+
qry2[k].emplace_back(r, i);
118+
} else {
119+
qry1[l - 1].emplace_back(k, -i);
120+
qry1[r].emplace_back(k, i);
121+
}
122+
}
123+
queue<int> q;
124+
for (int i = 0; i < 26; ++i)
125+
if (trie[1][i]) {
126+
q.push(trie[1][i]);
127+
fail[trie[1][i]] = 1;
128+
}
129+
while (!q.empty()) {
130+
int u = q.front(); q.pop();
131+
for (int i = 0; i < 26; ++i)
132+
if (trie[u][i]) {
133+
int p = fail[u];
134+
while (p != rt && !trie[p][i])
135+
p = fail[p];
136+
if (trie[p][i])
137+
fail[trie[u][i]] = trie[p][i];
138+
else
139+
fail[trie[u][i]] = rt;
140+
q.push(trie[u][i]);
141+
}
142+
}
143+
for (int i = 2; i <= vc; ++i)
144+
ch[fail[i]].push_back(i);
145+
dfs(1);
146+
for (int i = 1; i <= n; ++i) {
147+
change(dfn[vertex[i]], 1);
148+
change(dfnr[vertex[i]] + 1, -1);
149+
for (const auto& pr : qry1[i]) {
150+
int u = vertex[pr.first];
151+
if (pr.second < 0)
152+
for (; u != rt; u = prt[u])
153+
ans[-pr.second] -= query(dfn[u]);
154+
else
155+
for (; u != rt; u = prt[u])
156+
ans[pr.second] += query(dfn[u]);
157+
}
158+
}
159+
for (int i = 1; i <= n; ++i)
160+
if (!qry2[i].empty()) {
161+
memset(sub, 0, sizeof(sub));
162+
int u = vertex[i];
163+
for (; u != rt; u = prt[u])
164+
sub[u] = 1;
165+
dfs2(1);
166+
for (int j = 1; j <= n; ++j)
167+
pre[j] = pre[j - 1] + sub[vertex[j]];
168+
for (const auto& pr : qry2[i])
169+
if (pr.second < 0)
170+
ans[-pr.second] -= pre[pr.first];
171+
else
172+
ans[pr.second] += pre[pr.first];
173+
}
174+
for (int i = 1; i <= m; ++i)
175+
cout << ans[i] << '\n';
176+
177+
return 0;
178+
}

part2/checklist.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@
137137
- 随便用埃氏筛过程做几遍容斥即可 $\Theta(x\log\log x)$。
138138
- [ ] cf585F
139139
- [ ] cf587D
140-
- [ ] cf587F
140+
- [x] cf587F
141+
- 按 $k$ 串长度分块。长的 $k \rightarrow l, r$,短的 $l, r\rightarrow k$。
141142
- [ ] cf590E
142143
- [ ] cf594E
143144
- [ ] cf603E

0 commit comments

Comments
 (0)