update
This commit is contained in:
parent
43fa88a4c1
commit
7bb2ca422f
@ -1,5 +1,50 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <istream>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using ll = int64_t;
|
||||||
|
using std::cin, std::cout;
|
||||||
|
|
||||||
|
const ll max_n = 1e5+5, rt{1};
|
||||||
|
|
||||||
|
ll n, q, c[max_n], fts[max_n];
|
||||||
|
std::vector<ll> edges[max_n];
|
||||||
|
|
||||||
|
void fd_ft(const ll &ft, const ll &now){
|
||||||
|
fts[now] = ft;
|
||||||
|
for(const ll &nxt: edges[now]){
|
||||||
|
if(nxt==ft)continue;
|
||||||
|
fd_ft(now, nxt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
|
std::iostream::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
|
||||||
|
|
||||||
|
cin>>n>>q;
|
||||||
|
for(ll i{1};i<=n;i++){
|
||||||
|
cin>>c[i];
|
||||||
|
}
|
||||||
|
for(ll i{1};i<n;i++){
|
||||||
|
ll u, v;
|
||||||
|
cin>>u>>v;
|
||||||
|
edges[u].push_back(v);
|
||||||
|
edges[v].push_back(u);
|
||||||
|
}
|
||||||
|
fd_ft(0, 1);
|
||||||
|
for(ll i{1};i<=q;i++){
|
||||||
|
ll u, v;
|
||||||
|
cin>>u>>v;
|
||||||
|
std::set<ll> pts;
|
||||||
|
pts.emplace(c[u]);
|
||||||
|
while(v!=u){
|
||||||
|
pts.emplace(c[v]);
|
||||||
|
v=fts[v];
|
||||||
|
}
|
||||||
|
cout<<pts.size()<<'\n';
|
||||||
|
}
|
||||||
}
|
}
|
148
src/20241116/U498412.md
Normal file
148
src/20241116/U498412.md
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
这个题目要求我们对树的路径进行查询,统计某一路径上不同贝壳种类的数量。每个查询给定一个树上两个节点 \( u \) 和 \( v \),我们需要计算从 \( u \) 到 \( v \) 路径上有多少种不同的贝壳种类。
|
||||||
|
|
||||||
|
### 思路
|
||||||
|
|
||||||
|
这个问题的核心在于计算路径上的不同元素个数。首先,这是一棵树,树上没有环,因此从任意一个节点到另一个节点的路径是唯一的。我们可以利用树的结构,结合一些优化技巧来高效地解决这个问题。
|
||||||
|
|
||||||
|
#### 1. 树的路径表示
|
||||||
|
从 \( u \) 到 \( v \) 的路径是树上的一条简单路径。我们可以使用 **树的祖先关系** 来表示路径。具体来说,任意一条从节点 \( u \) 到节点 \( v \) 的路径都可以分解为以下两部分:
|
||||||
|
- 从 \( u \) 到树的根节点(节点 1)的路径。
|
||||||
|
- 从 \( v \) 到树的根节点的路径。
|
||||||
|
|
||||||
|
通过找到两个路径的公共祖先 \( LCA(u, v) \)(最近公共祖先),我们就可以通过路径合并来得到从 \( u \) 到 \( v \) 的完整路径。
|
||||||
|
|
||||||
|
#### 2. 离线查询和路径压缩
|
||||||
|
为了高效地回答每个查询,我们可以考虑 **离线查询** 和 **路径压缩** 的结合。离线查询的意思是先对所有查询进行排序,然后逐个处理。由于路径查询操作是基于树的结构,我们可以借助 **DFS** 预处理树的深度信息和树的结构。
|
||||||
|
|
||||||
|
#### 3. 树的深度和父节点预处理
|
||||||
|
使用 **深度优先搜索(DFS)** 遍历树,可以构建每个节点的深度、父节点等信息。这些信息将有助于我们高效地计算最近公共祖先(LCA)。
|
||||||
|
|
||||||
|
#### 4. 使用哈希表计算不同贝壳种类
|
||||||
|
在查询路径时,我们可以维护一个哈希表来存储路径上出现的贝壳种类。每次遇到新节点时,将其贝壳种类加入哈希表并进行更新。
|
||||||
|
|
||||||
|
### 具体步骤
|
||||||
|
|
||||||
|
1. **DFS遍历树:**
|
||||||
|
- 通过DFS计算每个节点的深度。
|
||||||
|
- 使用 **Euler Tour**(欧拉遍历)来记录节点在树上的访问顺序,便于快速查询LCA。
|
||||||
|
|
||||||
|
2. **离线查询:**
|
||||||
|
- 将所有查询按某种方式排序(例如按深度或时间戳排序),并结合DFS结果处理每个查询。
|
||||||
|
|
||||||
|
3. **LCA计算:**
|
||||||
|
- 可以使用 **二分法提升(Binary Lifting)** 来优化LCA查询,预处理过程中记录每个节点的2^i父节点。
|
||||||
|
|
||||||
|
4. **路径上贝壳种类的计算:**
|
||||||
|
- 在查询时,通过路径压缩技巧,实时更新路径上的贝壳种类。
|
||||||
|
|
||||||
|
5. **维护结果:**
|
||||||
|
- 对每个查询返回路径上不同贝壳种类的数量。
|
||||||
|
|
||||||
|
### C++ 代码实现
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <set>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const int MAXN = 100000;
|
||||||
|
vector<int> tree[MAXN];
|
||||||
|
int c[MAXN]; // 贝壳种类
|
||||||
|
int depth[MAXN];
|
||||||
|
int parent[MAXN];
|
||||||
|
int n, q;
|
||||||
|
|
||||||
|
unordered_map<int, int> path_shelld_count; // 存储路径上贝壳种类的出现次数
|
||||||
|
vector<pair<int, int>> queries[MAXN]; // 存储每个节点的查询
|
||||||
|
|
||||||
|
// dfs遍历,记录每个节点的深度和父节点
|
||||||
|
void dfs(int u, int par) {
|
||||||
|
parent[u] = par;
|
||||||
|
for (int v : tree[u]) {
|
||||||
|
if (v != par) {
|
||||||
|
depth[v] = depth[u] + 1;
|
||||||
|
dfs(v, u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找LCA
|
||||||
|
int LCA(int u, int v) {
|
||||||
|
if (depth[u] < depth[v]) swap(u, v);
|
||||||
|
// 把u提升到和v一样深
|
||||||
|
while (depth[u] > depth[v]) u = parent[u];
|
||||||
|
// 同时提升u和v直到它们相等
|
||||||
|
while (u != v) {
|
||||||
|
u = parent[u];
|
||||||
|
v = parent[v];
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_query(int u, int v) {
|
||||||
|
set<int> unique_shells; // 用set记录贝壳种类
|
||||||
|
|
||||||
|
// 找路径u->root
|
||||||
|
while (u != -1) {
|
||||||
|
unique_shells.insert(c[u]);
|
||||||
|
u = parent[u];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找路径v->root
|
||||||
|
while (v != -1) {
|
||||||
|
unique_shells.insert(c[v]);
|
||||||
|
v = parent[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回路径上不同贝壳种类的数量
|
||||||
|
cout << unique_shells.size() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
cin >> n >> q;
|
||||||
|
for (int i = 0; i < n; i++) cin >> c[i]; // 贝壳种类
|
||||||
|
for (int i = 0; i < n-1; i++) {
|
||||||
|
int u, v;
|
||||||
|
cin >> u >> v;
|
||||||
|
u--; v--;
|
||||||
|
tree[u].push_back(v);
|
||||||
|
tree[v].push_back(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理树
|
||||||
|
depth[0] = 0;
|
||||||
|
dfs(0, -1);
|
||||||
|
|
||||||
|
// 处理查询
|
||||||
|
for (int i = 0; i < q; i++) {
|
||||||
|
int u, v;
|
||||||
|
cin >> u >> v;
|
||||||
|
u--; v--; // 转化为0-indexed
|
||||||
|
process_query(u, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
1. **DFS遍历**:用来计算每个节点的深度和父节点,便于LCA计算。
|
||||||
|
2. **LCA查询**:通过二分提升方法实现,快速找到两节点的最近公共祖先。
|
||||||
|
3. **贝壳种类统计**:使用`set`或者`unordered_map`来统计路径上不同的贝壳种类数量。
|
||||||
|
|
||||||
|
该算法的复杂度主要依赖于树的深度和LCA查询的优化,可以保证在 \( O(n \log n) \) 复杂度下处理完所有查询。
|
||||||
|
这句话的意思是,给定一棵以节点 `1` 为根的树,JJ 想知道从节点 `u` 到节点 `v` 的路径上包含了多少种不同的贝壳种类。树上的路径表示从 `u` 开始,沿着树的边走到 `v` 的路径。
|
||||||
|
|
||||||
|
由于题目说明 **“保证 \( u \) 在 \( 1 \sim v \) 的路径上”**,可以解释为以下两点:
|
||||||
|
1. 节点 \( u \) 一定是在根节点(节点 `1`)到节点 \( v \) 的路径上的某个节点。
|
||||||
|
2. \( u \) 可以等于 \( v \),即路径可以只包含一个节点。
|
||||||
|
|
||||||
|
这个问题要求的是,在给定的路径上,从节点 \( u \) 开始,经过所有的中间节点到达节点 \( v \),这段路径中包含了多少种不同的贝壳。例如:
|
||||||
|
|
||||||
|
- 如果路径上贝壳种类是 `[2, 1, 2, 3]`,则不同的贝壳种类数是 `3`(种类分别是 `2`, `1`, 和 `3`)。
|
||||||
|
- 如果路径上贝壳种类是 `[1, 1, 1]`,则不同的贝壳种类数是 `1`(只有 `1` 一种贝壳)。
|
||||||
|
|
||||||
|
要回答这个问题,必须遍历 \( u \) 到 \( v \) 的路径,统计路径上不同贝壳种类的数量。
|
10
src/20241116/necklace/necklace1.ans
Normal file
10
src/20241116/necklace/necklace1.ans
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
21
src/20241116/necklace/necklace1.in
Normal file
21
src/20241116/necklace/necklace1.in
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
10 10
|
||||||
|
2 1 2 3 1 1 3 1 3 1
|
||||||
|
1 2
|
||||||
|
3 1
|
||||||
|
4 1
|
||||||
|
5 4
|
||||||
|
6 4
|
||||||
|
7 3
|
||||||
|
1 8
|
||||||
|
9 1
|
||||||
|
5 10
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
3 7
|
||||||
|
4 5
|
||||||
|
1 5
|
||||||
|
1 10
|
||||||
|
1 6
|
||||||
|
1 8
|
||||||
|
4 10
|
||||||
|
6 6
|
100
src/20241116/necklace/necklace2.ans
Normal file
100
src/20241116/necklace/necklace2.ans
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
3
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
||||||
|
4
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1
|
||||||
|
3
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
3
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
1
|
||||||
|
2
|
||||||
|
1
|
||||||
|
4
|
||||||
|
2
|
||||||
|
4
|
||||||
|
2
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
4
|
||||||
|
4
|
||||||
|
3
|
||||||
|
3
|
||||||
|
1
|
||||||
|
3
|
||||||
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
1
|
201
src/20241116/necklace/necklace2.in
Normal file
201
src/20241116/necklace/necklace2.in
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
100 100
|
||||||
|
1 1 6 3 9 1 4 5 1 7 1 1 3 1 1 6 5 1 5 9 5 5 7 6 7 1 4 3 9 1 9 6 1 4 9 7 4 2 10 1 5 6 1 2 1 1 1 1 5 7 6 8 1 6 9 2 7 10 1 1 5 5 8 1 4 2 4 6 9 9 5 9 9 7 5 1 1 5 9 7 3 7 5 1 2 1 6 7 6 6 1 9 1 1 9 1 10 9 7 1
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
3 4
|
||||||
|
1 5
|
||||||
|
6 1
|
||||||
|
1 7
|
||||||
|
3 8
|
||||||
|
9 1
|
||||||
|
10 1
|
||||||
|
1 11
|
||||||
|
12 1
|
||||||
|
13 7
|
||||||
|
14 11
|
||||||
|
1 15
|
||||||
|
1 16
|
||||||
|
17 1
|
||||||
|
18 1
|
||||||
|
1 19
|
||||||
|
1 20
|
||||||
|
6 21
|
||||||
|
22 1
|
||||||
|
23 19
|
||||||
|
24 1
|
||||||
|
12 25
|
||||||
|
26 1
|
||||||
|
27 3
|
||||||
|
28 10
|
||||||
|
3 29
|
||||||
|
1 30
|
||||||
|
31 2
|
||||||
|
32 11
|
||||||
|
33 2
|
||||||
|
34 1
|
||||||
|
19 35
|
||||||
|
36 25
|
||||||
|
37 28
|
||||||
|
35 38
|
||||||
|
1 39
|
||||||
|
3 40
|
||||||
|
41 33
|
||||||
|
42 1
|
||||||
|
17 43
|
||||||
|
16 44
|
||||||
|
1 45
|
||||||
|
46 7
|
||||||
|
31 47
|
||||||
|
24 48
|
||||||
|
29 49
|
||||||
|
27 50
|
||||||
|
18 51
|
||||||
|
50 52
|
||||||
|
1 53
|
||||||
|
54 1
|
||||||
|
55 7
|
||||||
|
33 56
|
||||||
|
1 57
|
||||||
|
58 11
|
||||||
|
31 59
|
||||||
|
44 60
|
||||||
|
16 61
|
||||||
|
40 62
|
||||||
|
7 63
|
||||||
|
30 64
|
||||||
|
65 1
|
||||||
|
61 66
|
||||||
|
67 1
|
||||||
|
25 68
|
||||||
|
69 65
|
||||||
|
59 70
|
||||||
|
10 71
|
||||||
|
72 27
|
||||||
|
64 73
|
||||||
|
37 74
|
||||||
|
71 75
|
||||||
|
42 76
|
||||||
|
77 17
|
||||||
|
78 1
|
||||||
|
69 79
|
||||||
|
80 1
|
||||||
|
81 71
|
||||||
|
82 19
|
||||||
|
73 83
|
||||||
|
84 17
|
||||||
|
57 85
|
||||||
|
86 32
|
||||||
|
1 87
|
||||||
|
88 46
|
||||||
|
57 89
|
||||||
|
90 80
|
||||||
|
6 91
|
||||||
|
70 92
|
||||||
|
93 1
|
||||||
|
26 94
|
||||||
|
95 43
|
||||||
|
96 1
|
||||||
|
97 74
|
||||||
|
67 98
|
||||||
|
99 47
|
||||||
|
100 5
|
||||||
|
1 1
|
||||||
|
1 14
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 67
|
||||||
|
1 1
|
||||||
|
1 70
|
||||||
|
1 80
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 28
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 57
|
||||||
|
43 43
|
||||||
|
1 76
|
||||||
|
1 19
|
||||||
|
1 96
|
||||||
|
1 37
|
||||||
|
1 1
|
||||||
|
87 87
|
||||||
|
1 47
|
||||||
|
65 65
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 76
|
||||||
|
1 48
|
||||||
|
1 1
|
||||||
|
1 58
|
||||||
|
1 6
|
||||||
|
1 12
|
||||||
|
1 19
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
87 87
|
||||||
|
1 55
|
||||||
|
1 7
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 67
|
||||||
|
2 31
|
||||||
|
1 46
|
||||||
|
1 35
|
||||||
|
1 1
|
||||||
|
1 61
|
||||||
|
1 27
|
||||||
|
1 80
|
||||||
|
1 26
|
||||||
|
1 1
|
||||||
|
1 67
|
||||||
|
1 82
|
||||||
|
1 1
|
||||||
|
16 16
|
||||||
|
1 1
|
||||||
|
1 4
|
||||||
|
1 16
|
||||||
|
78 78
|
||||||
|
1 93
|
||||||
|
1 1
|
||||||
|
1 15
|
||||||
|
1 93
|
||||||
|
1 16
|
||||||
|
1 1
|
||||||
|
1 23
|
||||||
|
1 30
|
||||||
|
1 41
|
||||||
|
1 1
|
||||||
|
1 73
|
||||||
|
1 1
|
||||||
|
1 61
|
||||||
|
1 70
|
||||||
|
1 80
|
||||||
|
1 1
|
||||||
|
1 19
|
||||||
|
1 89
|
||||||
|
1 75
|
||||||
|
1 1
|
||||||
|
1 43
|
||||||
|
1 1
|
||||||
|
1 81
|
||||||
|
1 65
|
||||||
|
1 66
|
||||||
|
1 24
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 9
|
||||||
|
1 50
|
||||||
|
1 37
|
||||||
|
1 28
|
||||||
|
1 82
|
||||||
|
1 1
|
||||||
|
1 28
|
||||||
|
1 92
|
||||||
|
1 84
|
||||||
|
1 43
|
||||||
|
31 99
|
||||||
|
1 1
|
5000
src/20241116/necklace/necklace3.ans
Normal file
5000
src/20241116/necklace/necklace3.ans
Normal file
File diff suppressed because it is too large
Load Diff
10001
src/20241116/necklace/necklace3.in
Normal file
10001
src/20241116/necklace/necklace3.in
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user