1. 栈
- 103 出栈序列判断

点击查看代码
const int N = 2e5 + 10;
int n, top, stk[N];
void solve() {
scanf("%d", &n);
top = 0;
int x = 0;
for (int i = 1; i <= n; i ++) {
int t; scanf("%d", &t);
if (stk[top] != t) {
for (int j = x + 1; j <= t; j ++) {
stk[++ top] = j;
printf("push %d\n", j);
}
x = t;
printf("pop\n");
top --;
} else {
top --;
printf("pop\n");
}
}
}
- 104 括号序列

容易漏掉一种左括号没有匹配完的情况
点击查看代码
const int N = 2e5 + 10;
int n, top;
char stk[N];
void solve() {
scanf("%d", &n);
if (n & 1) {
cout << "No" << endl;
return ;
}
top = 0;
for (int i = 1; i <= n; i ++) {
char ch; cin >> ch;
if (ch == '(' || ch == '[') stk[++ top] = ch;
else {
if (ch == ')') {
if (top == 0) {
cout << "No" << endl;
return ;
}
if (stk[top] == '(') top --;
else {
cout << "No" << endl;
return ;
}
} else {
if (top == 0) {
cout << "No" << endl;
return ;
}
if (stk[top] == '[') top --;
else {
cout << "No" << endl;
return ;
}
}
}
}
if (top != 0) {
cout << "No" << endl;
return ;
}
cout << "Yes" << endl;
}
- 105 字符串处理1

点击查看代码
const int N = 2e5 + 10;
int n, top;
pair<char, int> stk[N];
bool st[N];
void solve() {
scanf("%d", &n);
string s; cin >> s;
for (int i = 0; i < n; i ++) {
if (top == 0 || stk[top].fi != s[i]) {
stk[++ top] = {s[i], i};
continue;
}
if (stk[top].fi == s[i]) {
st[stk[top].sc] = true;
st[i] = true;
top --;
}
}
for (int i = 0; i < n; i ++) {
if (!st[i]) cout << s[i];
}
cout << endl;
}
- 106 字符串处理2

点击查看代码
const int N = 2e5 + 10;
int n, top;
pair<char, int> stk[N];
bool st[N];
void solve() {
scanf("%d", &n);
string s; cin >> s;
for (int i = 0; i < n; i ++) {
if (s[i] >= 'A' && s[i] <= 'Z') {
if (top == 0 || stk[top].fi != s[i] - 'A' + 'a') {
stk[++ top] = {s[i], i};
continue;
}
if (stk[top].fi == s[i] - 'A' + 'a') {
st[stk[top].sc] = true;
st[i] = true;
top --;
}
} else {
if (top == 0 || stk[top].fi != s[i] - 'a' + 'A') {
stk[++ top] = {s[i], i};
continue;
}
if (stk[top].fi == s[i] - 'a' + 'A') {
st[stk[top].sc] = true;
st[i] = true;
top --;
}
}
}
for (int i = 1; i <= top; i ++) {
cout << stk[i].fi;
}
cout << endl;
}
- 107 出栈序列

点击查看代码
int n, top;
stack<int> stk;
vector<int> v;
int nw;
void dfs() {
if (v.size() == n) {
for (auto x : v)
printf("%d ", x);
printf("\n");
return ;
}
if (!stk.empty()) {
v.push_back(stk.top());
stk.pop();
dfs();
stk.push(v.back());
v.pop_back();
}
if (nw < n) {
nw ++;
stk.push(nw);
dfs();
stk.pop();
nw --;
}
}
void solve() {
scanf("%d", &n);
nw = 0;
dfs();
return ;
}
2.队列
- 203 数字统计

点击查看代码
int n, q[N], hh, tt;
void solve() {
cin >> n;
hh = 0;
tt = -1;
for (int i = 1; i <= n; i ++) {
int x; cin >> x;
while (q[hh] + 5 < x && hh <= tt) hh ++;
//cout << hh <<" ' " << tt << endl;
q[++ tt] = x;
cout << tt - hh << ' ';
}
return ;
}
- 204排队买票

点击查看代码
const int N = 1e6 + 10;
int n, hh, tt;
PII q[N];
int ans[N];
void solve() {
cin >> n;
hh = 0;
tt = -1;
for (int i = 1; i <= n; i ++) {
int x; cin >> x;
q[++ tt] = {x, i};
}
int t = 0;
while (true) {
PII x = q[hh ++];
x.fi --;
t ++;
if (x.fi == 0) {
ans[x.sc] = t;
if (hh > tt) break;
else continue;
}
else {
q[++ tt] = x;
}
}
for (int i = 1; i <= n; i ++)
cout << ans[i] << ' ';
cout << endl;
return ;
}
- 205 约瑟夫问题

点击查看代码
const int N = 1e6 + 10;
int n, m, hh, tt;
int q[N];
int ans[N];
void solve() {
cin >> n >> m;
hh = 0;
tt = -1;
for (int i = 1; i <= n; i ++) {
q[++ tt] = i;
}
int t = 0, num = 1, cn = n;
while (true) {
int x = q[hh ++];
t ++;
if (t == m) {
t = 0;
ans[x] = num ++;
cn --;
cout << x << ' ';
if (cn == 0) break;
continue;
} else {
q[++ tt] = x;
}
}
return ;
}
- 206 循环队列练习

点击查看代码
const int N = 1e6 + 10;
int n, m, hh, tt;
int q[N];
int ans[N];
int sz = 1001;
char s[20];
void solve() {
cin >> m;
hh = 1, tt = 0;
while (m --) {
scanf("%s", s);
if (s[2] == 's') {
int x; scanf("%d", &x);
tt = tt % sz + 1;
q[tt] = x;
} else if (s[1] == 'o') {
hh %= sz;
hh ++;
} else {
int x; scanf("%d", &x);
if (x + hh - 1 <= sz) printf("%d\n", q[hh + x - 1]);
else printf("%d\n", q[hh + x - 1 - sz]);
}
}
return ;
}
3. 树
点击查看代码
struct Node{
int l, r, fa;
} node[N];
void dfs(int id) {
node[id].l = id * 2;
node[id].r = id * 2 + 1;
node[id].fa = id / 2;
if (id >= n) return ;
if (node[id].l <= n) dfs(node[id].l);
if (node[id].r <= n) dfs(node[id].r);
}
void init() {
dfs(1);
}
void preorder(int id) {
cout << id << ' ';
if (node[id].l <= n) preorder(node[id].l);
if (node[id].r <= n) preorder(node[id].r);
}
void inorder(int id) {
if (node[id].l <= n) inorder(node[id].l);
cout << id << ' ';
if (node[id].r <= n) inorder(node[id].r);
}
void postorder(int id) {
if (node[id].l <= n) postorder(node[id].l);
if (node[id].r <= n) postorder(node[id].r);
cout << id << ' ';
}
- 402 遍历一般二叉树

点击查看代码
const int N = 1e6 + 10;
int n, m;
int ans[N];
struct Node{
int l, r, fa;
} node[N];
void dfs(int id) {
node[id].l = id * 2;
node[id].r = id * 2 + 1;
node[id].fa = id / 2;
if (id >= n) return ;
if (node[id].l <= n) dfs(node[id].l);
if (node[id].r <= n) dfs(node[id].r);
}
void init() {
for (int i = 1; i <= n; i ++) {
int x, y; cin >> x >> y;
node[i].l = x, node[i].r = y;
}
}
void preorder(int id) {
cout << id << ' ';
if (node[id].l <= n && node[id].l != 0) preorder(node[id].l);
if (node[id].r <= n && node[id].r != 0) preorder(node[id].r);
}
void inorder(int id) {
if (node[id].l <= n && node[id].l != 0) inorder(node[id].l);
cout << id << ' ';
if (node[id].r <= n && node[id].r != 0) inorder(node[id].r);
}
void postorder(int id) {
if (node[id].l <= n && node[id].l != 0) postorder(node[id].l);
if (node[id].r <= n && node[id].r != 0) postorder(node[id].r);
cout << id << ' ';
}
void solve() {
cin >> n;
init();
preorder(1);
cout << endl;
inorder(1);
cout << endl;
postorder(1);
cout << endl;
return ;
}
- 403 二叉树的最近公共祖先

点击查看代码
const int N = 1e6 + 10;
int n, m;
int ans[N];
struct Node{
int l, r, fa;
int dep;
} node[N];
void dfs(int id) {
if (node[id].l) {
node[node[id].l].dep = node[id].dep + 1;
dfs(node[id].l);
}
if (node[id].r) {
node[node[id].r].dep = node[id].dep + 1;
dfs(node[id].r);
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
int x, y; cin >> x >> y;
if (x) node[i].l = x, node[x].fa = i;
if (y) node[i].r = y, node[y].fa = i;
}
node[1].dep = 1;
dfs(1);
int u, v; cin >> u >> v;
if (node[u].dep < node[v].dep) swap(u, v);
int x = node[u].dep - node[v].dep;
for (int i = 1; i <= x; i ++)
u = node[u].fa;
while (u != v) {
u = node[u].fa;
v = node[v].fa;
}
cout << u << endl;
return ;
}
- 404&405 二叉树子树和1&2

点击查看代码
const int N = 1e6 + 10;
int n, m;
int ans[N];
struct Node{
int l, r, fa;
int dep;
ll sum;
} node[N];
void dfs(int id) {
if (node[id].l) {
node[node[id].l].dep = node[id].dep + 1;
dfs(node[id].l);
node[id].sum += node[node[id].l].sum;
}
if (node[id].r) {
node[node[id].r].dep = node[id].dep + 1;
dfs(node[id].r);
node[id].sum += node[node[id].r].sum;
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
int x, y; cin >> x >> y;
if (x) node[i].l = x, node[x].fa = i;
if (y) node[i].r = y, node[y].fa = i;
}
for (int i = 1; i <= n; i ++) {
cin >> node[i].sum;
}
node[1].dep = 1;
dfs(1);
for (int i = 1; i <= n; i ++)
cout << node[i].sum << ' ';
return ;
}
- 406 先序中序转后序

点击查看代码
const int N = 1e6 + 10;
int n, m;
int ans[N];
int a[N], b[N], c[N];
struct Node{
int l, r, fa;
int dep;
ll sum;
} node[N];
void dfs(int id) {
if (node[id].l) {
node[node[id].l].dep = node[id].dep + 1;
dfs(node[id].l);
node[id].sum += node[node[id].l].sum;
}
if (node[id].r) {
node[node[id].r].dep = node[id].dep + 1;
dfs(node[id].r);
node[id].sum += node[node[id].r].sum;
}
}
void transfer_to_pre(int id, int l, int r) {
if (l > r) return ;
int p = l;
while (p < r && a[p] != b[id]) p ++;
transfer_to_pre(id + 1, l, p - 1);
transfer_to_pre(id + (p - l + 1), p + 1, r);
cout << b[id] << ' ';
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> b[i];
for (int i = 1; i <= n; i ++) cin >> a[i];
transfer_to_pre(1, 1, n);
return ;
}
- 407 中序后序转先序

点击查看代码
const int N = 1e6 + 10;
int n, m;
int ans[N];
int a[N], b[N], c[N];
struct Node{
int l, r, fa;
int dep;
ll sum;
} node[N];
void dfs(int id) {
if (node[id].l) {
node[node[id].l].dep = node[id].dep + 1;
dfs(node[id].l);
node[id].sum += node[node[id].l].sum;
}
if (node[id].r) {
node[node[id].r].dep = node[id].dep + 1;
dfs(node[id].r);
node[id].sum += node[node[id].r].sum;
}
}
void transfer_to_pre(int id, int l, int r) {
if (l > r) return ;
int p = l;
while (p < r && a[p] != b[id]) p ++;
cout << b[id] << ' ';
transfer_to_pre(id - (r - p + 1), l, p - 1);
transfer_to_pre(id - 1, p + 1, r);
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) cin >> b[i];
transfer_to_pre(n, 1, n);
return ;
}
4. 哈希
- 504 构造最长回文数组

点击查看代码
const int N = 1e6 + 10;
int n, m;
map<int, int> mp;
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
int x; cin >> x;
mp[x] ++;
}
ll ans = 0;
bool ok = false;
for (auto x : mp) {
if (x.sc & 1) {
ok = true;
ans += (x.sc - 1);
} else {
ans += x.sc;
}
}
if (ok) ans ++;
cout << ans << endl;
return ;
}
- 505 小蜗的疑问

点击查看代码
const int N = 1e6 + 10;
const int base = 31;
const int p = 9999971;
int n, m;
int ha[N], hb[N], c[N];
void solve() {
cin >> n >> m;
string s, t; cin >> s >> t;
s = " " + s;
t = " " + t;
c[0] = 1;
for (int i = 1; i <= 200000; i ++)
c[i] = c[i - 1] * base % p;
for (int i = 1; i <= n; i ++)
ha[i] = (ha[i - 1] * base + (s[i] - 'a')) % p;
for (int i = 1; i <= m; i ++)
hb[i] = (hb[i - 1] * base + (t[i] - 'a')) % p;
int ans = 0;
for (int i = 1; i + m - 1 <= n; i ++)
if ((ha[i + m - 1] - 1LL * ha[i - 1] * c[m] % p + p) % p == hb[m])
ans ++;
cout << ans << endl;
return ;
}
5. 堆
- 602 合并数列

点击查看代码
const int N = 1e6 + 10;
const int base = 31;
const int p = 9999971;
int n, m;
void solve() {
cin >> n;
priority_queue<PII, vector<PII>, greater<PII> > pq;
for (int i = 1; i <= n; i ++) {
int k, b; cin >> k >> b;
pq.push({b, k});
}
cin >> m;
while (m --) {
PII now = pq.top();
pq.pop();
cout << now.fi << ' ';
pq.push({now.fi + now.sc, now.sc});
}
return ;
}
- 604 动态中位数

点击查看代码
void solve() {
cin >> n;
priority_queue<ll> pq1; //大根堆
priority_queue<ll, vector<ll>, greater<ll> > pq2; //小根堆
for (int i = 1; i <= n; i ++) {
int x; cin >> x;
if (pq1.empty() || x <= pq1.top()) pq1.push(x);
else pq2.push(x);
if (pq1.size() > (i + 1) / 2) pq2.push(pq1.top()), pq1.pop();
if (pq2.size() > i / 2) pq1.push(pq2.top()), pq2.pop();
if (i & 1) {
cout << pq1.top() << endl;
}
}
return ;
}
6. 单调栈单调队列
- 701 求下一个更大数

点击查看代码
int n, m;
int a[N], ans[N];
void solve() {
cin >> n;
stack<PII> stk;
for (int i = 1; i <= n; i ++) {
int x; cin >> x;
while (stk.size() && stk.top().fi < x) {
ans[stk.top().sc] = i;
stk.pop();
}
stk.push({x, i});
}
while (stk.size()) {
ans[stk.top().sc] = 0;
stk.pop();
}
for (int i = 1; i <= n; i ++)
cout << ans[i] << ' ';
cout << endl;
return ;
}
- 702 最大矩形面积

点击查看代码
int n, m;
ll a[N], ans[N];
int l[N], r[N];
void solve() {
cin >> n;
stack<int> stk;
for (int i = 1; i <= n; i ++)
cin >> a[i];
// 求出每个数左边第一个比他小的
for (int i = n; i >= 1; i --) {
while (stk.size() && a[stk.top()] > a[i]) {
l[stk.top()] = i;
stk.pop();
}
stk.push(i);
}
while (stk.size()) {
l[stk.top()] = 0;
stk.pop();
}
// 求出每个数右边第一个比他小的
for (int i = 1; i <= n; i ++) {
while (stk.size() && a[stk.top()] > a[i]) {
r[stk.top()] = i;
stk.pop();
}
stk.push(i);
}
while (stk.size()) {
r[stk.top()] = n + 1;
stk.pop();
}
// for (int i = 1; i <= n; i ++)
// cout << l[i] << ' ';
// cout << endl;
// for (int i = 1; i <= n; i ++)
// cout << r[i] << ' ';
// cout << endl;
ll mx = -1;
for (int i = 1; i <= n; i ++) {
ans[i] = (r[i] - l[i] - 1) * a[i];
mx = max(ans[i], mx);
}
cout << mx << endl;
return ;
}
- 703 数对统计2

点击查看代码
void solve() {
cin >> n;
stack<int> stk;
int ans = 0;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= n; i ++) {
while (stk.size() && a[stk.top()] < a[i]) {
ans ++;
//cout << i << endl;
stk.pop();
}
if (stk.size()) ans ++;
//cout << ans << endl;
stk.push(i);
}
cout << ans << endl;
return ;
}
- 704 动态区间最大数

点击查看代码
const int N = 1e6 + 10;
int n, m;
int a[N], q[N];
int hh = 0, tt = -1;
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= n; i ++) {
while (hh <= tt && a[q[tt]] <= a[i]) tt --;
q[++ tt] = i;
if (i - q[hh] + 1 > m) hh ++;
if (i >= m) cout << a[q[hh]] << ' ';
}
return ;
}
- 705 最大连续区间和

点击查看代码
const int N = 1e6 + 10;
int n, m, l, r;
int a[N], q[N], s[N];;
int hh = 0, tt = -1;
void solve() {
cin >> n >> l >> r;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= n; i ++)
s[i] = s[i - 1] + a[i];
int ans = -1 << 30, x = l;
for (int i = 1; i + l - 1 <= n; i ++) {
while (x <= i + r - 1 && x <= n) {
while (hh <= tt && s[q[tt]] <= s[x]) tt --;
q[++ tt] = x ++;
}
if (q[hh] < i + l - 1) hh ++;
ans = max(ans, s[q[hh]] - s[i - 1]);
}
cout << ans << endl;
return ;
}
- 706 覆盖

点击查看代码
const int N = 1e6 + 10;
int n, m, h;
int a[N], q1[N], q2[N];
int hh1 = 1, tt1 = 0, hh2 = 1, tt2 = 0;
void solve() {
cin >> n >> h;
for (int i = 1; i <= n; i ++) cin >> a[i];
int j = 0, ans = 0;
for (int i = 1; i <= n; i ++) {
if (hh1 <= tt1 && q1[hh1] < i) hh1 ++;
if (hh2 <= tt2 && q2[hh2] < i) hh2 ++;
while (j <= n && (j <= i || a[q1[hh1]] - a[q2[hh2]] <= h)) {
j ++;
if (j > n) break;
while (hh1 <= tt1 && a[q1[tt1]] <= a[j]) tt1 --;
q1[++ tt1] = j;
while (hh2 <= tt2 && a[q2[tt2]] >= a[j]) tt2 --;
q2[++ tt2] = j;
}
ans = max(ans, j - i);
}
cout << ans << endl;
return ;
}
7. 树
- 801 求树上路径

点击查看代码
const int N = 1e6 + 10;
int n, m;
vector<int> edge[N];
int pre[N];
void dfs(int st, int ed, int nw, int from) {
pre[nw] = from;
for (auto x : edge[nw]) {
if (x != from) {
dfs(st, ed, x, nw);
}
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n - 1; i ++) {
int x, y; cin >> x >> y;
edge[x].push_back(y);
edge[y].push_back(x);
}
int u, v; cin >> u >> v;
dfs(u, v, u, -1);
int x = v;
vector<int> ans;
ans.push_back(v);
while (pre[x] != -1) {
ans.push_back(pre[x]);
x = pre[x];
}
reverse(ans.begin(), ans.end());
for (auto x : ans)
cout << x << ' ';
return ;
}
- 802 树的直径

点击查看代码
const int N = 1e6 + 10;
int n, m;
vector<int> edge[N];
int dist[N];
void dfs(int nw, int from) {
for (auto x : edge[nw]) {
if (x != from) {
dist[x] = dist[nw] + 1;
dfs(x, nw);
}
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n - 1; i ++) {
int x, y; cin >> x >> y;
edge[x].push_back(y);
edge[y].push_back(x);
}
dist[1] = 0;
dfs(1, -1);
int id, mx = -1;
for (int i = 1; i <= n; i ++) {
if (dist[i] > mx) {
mx = dist[i];
id = i;
}
}
memset(dist, 0, sizeof dist);
dfs(id, -1);
cout << *max_element(dist + 1, dist + n + 1) << endl;
return ;
}
- 804 最小距离和2

点击查看代码
const int N = 1e6 + 10;
int n, m;
vector<int> edges[N];
ll dist[N], sz[N], pre[N];
void calc(int nw) {
sz[nw] = 1;
for (auto x : edges[nw]) {
if (x != pre[nw]) {
pre[x] = nw;
calc(x);
sz[nw] += sz[x];
}
}
}
void dfs(int nw) {
for (auto x : edges[nw]) {
if (x != pre[nw]) {
pre[x] = nw;
dist[x] = dist[nw] + 1;
dfs(x);
}
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n - 1; i ++) {
int x, y; cin >> x >> y;
edges[x].push_back(y);
edges[y].push_back(x);
}
pre[1] = -1;
calc(1);
int id, mi = 1 << 30;
for (int i = 1; i <= n; i ++) {
ll f = 0;
for (auto x : edges[i]) {
if (x != pre[i]) {
f = max(f, sz[x]);
} else {
f = max(f, n - sz[i]);
}
}
if (mi > f) {
mi = f;
id = i;
}
}
memset(pre, -1, sizeof pre);
dist[id] = 0;
dfs(id);
ll ans = 0;
for (int i = 1; i <= n; i ++) {
ans += dist[i];
}
cout << ans << endl;
return ;
}
- 805 树上LCA1

点击查看代码
const int N = 1e6 + 10;
int n, m;
vector<int> edges[N];
int dist[N], fa[N];
void dfs(int nw) {
for (auto x : edges[nw]) {
dist[x] = dist[nw] + 1;
dfs(x);
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n - 1; i ++) {
int x, y; cin >> x >> y;
edges[x].push_back(y);
fa[y] = x;
}
dist[1] = 0;
dfs(1);
cin >> m;
while (m --) {
int x, y; cin >> x >> y;
if (dist[x] < dist[y]) swap(x, y);
int z = dist[x] - dist[y];
for (int i = 1; i <= z; i ++) x = fa[x];
while (x != y) x = fa[x], y = fa[y];
cout << x << endl;
}
return ;
}
- 806 树上LCA2

点击查看代码
const int N = 1e6 + 10;
int n, m;
vector<int> edges[N];
int dist[N], fa[N][32];
void dfs(int nw) {
for (auto x : edges[nw]) {
dist[x] = dist[nw] + 1;
dfs(x);
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n - 1; i ++) {
int x, y; cin >> x >> y;
edges[x].push_back(y);
fa[y][0] = x;
}
for (int j = 1; j <= 30; j ++)
for (int i = 1; i <= n; i ++)
if (fa[i][j - 1])
fa[i][j] = fa[fa[i][j - 1]][j - 1];
dist[1] = 0;
dfs(1);
cin >> m;
while (m --) {
int x, y; cin >> x >> y;
if (dist[x] < dist[y]) swap(x, y);
int z = dist[x] - dist[y];
for (int i = 0; i <= 30 && z; i ++, z /= 2)
if (z & 1) {
x = fa[x][i];
}
if (x == y) {
cout << x << endl;
continue;
}
for (int i = 30; i >= 0; i --)
if (fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
cout << fa[x][0] << endl;
}
return ;
}
8. 字典树
- 901 字典树例题

点击查看代码
const int N = 1e6 + 10;
int n, m;
int nxt[N][26];
bool isend[N];
int cn;
void insert(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'z'])
nxt[nw][s[i] - 'z'] = ++ cn;
nw = nxt[nw][s[i] - 'z'];
}
isend[nw] = true;
}
bool query(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'z'])
return false;
nw = nxt[nw][s[i] - 'z'];
}
return isend[nw];
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
string s; cin >> s;
insert(s);
}
cin >> m;
while (m --) {
string s; cin >> s;
cout << query(s) << endl;
}
return ;
}
- 902 前缀次数统计

点击查看代码
const int N = 1e6 + 10;
int n, m;
int nxt[N][26], sum[N];
bool isend[N];
int cn;
void insert(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'a'])
nxt[nw][s[i] - 'a'] = ++ cn;
nw = nxt[nw][s[i] - 'a'];
sum[nw] ++;
}
isend[nw] = true;
}
bool query(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'a'])
return false;
nw = nxt[nw][s[i] - 'a'];
}
return isend[nw];
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
string s; cin >> s;
insert(s);
}
cin >> m;
while (m --) {
string s; cin >> s;
int sz = s.size();
int nw = 0;
bool ok = true;
for (int i = 0; i < sz && ok; i ++) {
if (!nxt[nw][s[i] - 'a']) ok = false;
nw = nxt[nw][s[i] - 'a'];
}
if (!ok) {
cout << 0 << endl;
} else {
cout << sum[nw] << endl;
}
}
return ;
}
- 903 字符串排序

点击查看代码
const int N = 1e6 + 10;
int n, m;
int nxt[N][26];
bool isend[N];
int cn;
string s;
void dfs(int nw, int dep) {
if (isend[nw])
cout << s << endl;
for (int i = 0; i < 26; i ++) {
if (nxt[nw][i]) {
char t = i + 'a';
string copy = s;
s = s + t;
dfs(nxt[nw][i], dep + 1);
s = copy;
}
}
}
void insert(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'a'])
nxt[nw][s[i] - 'a'] = ++ cn;
nw = nxt[nw][s[i] - 'a'];
}
isend[nw] = true;
}
bool query(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'a'])
return false;
nw = nxt[nw][s[i] - 'a'];
}
return isend[nw];
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
string s; cin >> s;
insert(s);
}
dfs(0, 0);
return ;
}
- 904 最长公共前缀问题

点击查看代码
const int N = 1e6 + 10;
int n, m;
int nxt[N][26];
bool isend[N];
int cn;
int idx[N], dep[N];
int fa[N][30];
void insert(int id, string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'a']) {
nxt[nw][s[i] - 'a'] = ++ cn;
dep[nxt[nw][s[i] -'a']] = dep[nw] + 1;
fa[nxt[nw][s[i] - 'a']][0] = nw;
}
nw = nxt[nw][s[i] - 'a'];
}
isend[nw] = true;
idx[id] = nw;
}
bool query(string s) {
int sz = s.size();
int nw = 0;
for (int i = 0; i < sz; i ++) {
if (!nxt[nw][s[i] - 'a'])
return false;
nw = nxt[nw][s[i] - 'a'];
}
return isend[nw];
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) {
string s; cin >> s;
insert(i, s);
}
for (int j = 1; j <= 20; j ++)
for (int i = 1; i <= cn; i ++)
if (fa[i][j - 1])
fa[i][j] = fa[fa[i][j - 1]][j - 1];
cin >> m;
while (m --) {
int x, y; cin >> x >> y;
x = idx[x], y = idx[y];
if (dep[x] < dep[y]) swap(x, y);
int z = dep[x] - dep[y];
for (int i = 0; i < 20 && z; i ++, z /= 2)
if (z & 1)
x = fa[x][i];
if (x == y) {
cout << dep[x] << endl;
continue;
}
for (int i = 20; i >= 0; i --)
if (fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
cout << dep[fa[x][0]] << endl;
}
return ;
}
9. 并查集
- 1001 并查集例题

点击查看代码
const int N = 1e6 + 10;
int n, m;
int fa[N];
int find(int x) {
if (x == fa[x]) return fa[x];
return fa[x] = find(fa[x]);
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i ++)
fa[i] = i;
while (m --) {
char ch;
int x, y;
cin >> ch >> x >> y;
if (ch == 'M') {
x = find(x), y = find(y);
fa[x] = y;
} else {
x = find(x), y = find(y);
if (x == y) cout << 1 << endl;
else cout << 0 << endl;
}
}
return ;
}
- 1002 修路

点击查看代码
const int N = 1e6 + 10;
int n, m;
int fa[N];
int find(int x) {
if (x == fa[x]) return fa[x];
return fa[x] = find(fa[x]);
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i ++)
fa[i] = i;
for (int i = 1; i <= m; i ++) {
int x, y; cin >> x >> y;
x = find(x), y = find(y);
fa[x] = y;
}
set<int> se;
for (int i = 1; i <= n; i ++) {
int x = find(i);
se.insert(x);
}
cout << se.size() - 1 << endl;
return ;
}
- 1003 行进路线

点击查看代码
const int N = 1e6 + 10;
int n, m;
int fa[N];
struct Node{
ll x, y, r;
} node[N];
int find(int x) {
if (x == fa[x]) return fa[x];
return fa[x] = find(fa[x]);
}
void solve() {
ll xe, ye; cin >> xe >> ye;
cin >> n;
node[0].x = 0, node[0].y = 0, node[0].r = 1;
for (int i = 1; i <= n; i ++)
cin >> node[i].x >> node[i].y >> node[i].r;
for (int i = 0; i <= n; i ++)
fa[i] = i;
for (int i = 0; i <= n; i ++)
for (int j = i + 1; j <= n; j ++)
if ((node[i].x - node[j].x) * (node[i].x - node[j].x) +
(node[i].y - node[j].y) * (node[i].y - node[j].y) <=
(node[i].r + node[j].r) * (node[i].r + node[j].r)) {
int fx = find(i), fy = find(j);
if (fx == fy) continue;
fa[fx] = fy;
}
int idx = -1;
for (int i = 0; i <= n; i ++) {
if ((node[i].x - xe) * (node[i].x - xe) +
(node[i].y - ye) * (node[i].y - ye) <=
node[i].r * node[i].r) {
idx = i;
}
}
if (idx != -1 && find(0) == find(idx))
cout << 1 << endl;
else
cout << 0 << endl;
return ;
}