文章目录
2020牛客暑期多校训练营(第五场)题解及补题
比赛过程
这场打出了排名新低,总结原因是前期还行中规中矩,后期两个中等难度的签到题罚时炸了。D和E犯了很多低级的错误,其中E不够熟悉大数板子,而且一开始过于急躁随便就觉得是把所有长度乘起来wa了之后才去认真思考,以后可以多花时间验证思想正确性,纯感觉流不太行。E思路正确,代码挫了,码力有待提升。
题解
A
题意
解法
代码
//将内容替换成代码
B
题意
n n n个点的一棵树,可以任意增减边(要求图联通且环的异或和为0),问修改后的树最小权值和。
解法
首先可以注意到,无论如何增删边,不会改变两个点路径的边的异或和,那么我们可以由这个特性给每个点一个权值,答案即为异或最小生成树。计算异或最小生成树主要用到了是 B o r u v k a Boruvka Boruvka算法和01字典树,因为其中有一个求最小异或对的过程,暴力是 n 2 n^2 n2的复杂度, t r i e trie trie可以用来优化第二层循环,因为对于每个数我们可以从高到低的去贪心选择数位一样的数。 B o r u v k a Boruvka Boruvka算法重点在于思想本身,这个算法一般情况下比 p r i m prim prim和 k r u s k a l kruskal kruskal要麻烦得多不会用但是在边权由两个点点权决定的题里有奇效, b o r u v k a boruvka boruvka相当于是两个思想的结合,多源的去做 p r i m prim prim。
代码
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 111;
const ll mod = 1e9 + 7;
#define P pair<int, int>
int trie[maxn * 32][2], idx;
vector<P> G[maxn];
int val[maxn];
void add(int a) {
int p = 0;
for (int i = 29; i >= 0; --i) {
bool tp = a & (1 << i);
if (!trie[p][tp]) trie[p][tp] = ++idx;
p = trie[p][tp];
}
}
int query(int a) {
//查找和a异或最小的数
int p = 0, ans = 0;
for (int i = 29; i >= 0; --i) {
bool tp = a & (1 << i);
if (trie[p][tp]) {
p = trie[p][tp];
} else {
ans |= (1 << i);
p = trie[p][!tp];
}
}
return ans;
}
void dfs(int u, int fa) {
for (auto v : G[u]) {
if (v.first == fa) continue;
val[v.first] = val[u] ^ v.second;
dfs(v.first, u);
}
}
ll ans;
void solve(int id, int l, int r) {
if (id < 0) return;
int mid = l - 1;
while (mid < r && (val[mid + 1] & (1 << id)) == 0) mid++;
if (l <= mid) solve(id - 1, l, mid);
if (mid + 1 <= r) solve(id - 1, mid + 1, r);
if (l <= mid && mid + 1 <= r) {
for (int i = l; i <= mid; i++) add(val[i]);
int minn = INT_MAX;
for (int i = mid + 1; i <= r; i++) minn = min(minn, query(val[i]));
for (int i = 0; i <= idx; ++i) {
trie[i][0] = trie[i][1] = 0;
}
idx = 0;
ans += minn;
}
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i < n; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w