int solve() {
int n; cin >> n;
int res = 0;
while (n --) {
int x; cin >> x;
res ++;
if (res == x) res ++;
}
return res;
}
int solve() {
int n; cin >> n;
vector<vector<int>> e(N), g(N);
set<int> st;
for (int i = 1; i <= n; i ++) {
int k; cin >> k;
while (k --) {
int x; cin >> x;
st.insert(x);
e[i].push_back(x); // 集合 i 存放的数
g[x].push_back(i); // 数 x 存放的集合序号
}
}
int res = 0;
for (auto u : st) { // 枚举删除每个变量
vector<bool> vis(N);
set<int> s;
for (auto i : g[u]) vis[i] = true; // vis[i] 表示集合 i 被删除
for (int i = 1; i <= n; i ++)
if (!vis[i])
for (auto j : e[i]) s.insert(j);
res = max(res, (int)s.size());
}
return res;
}
题解 从后面往前面删掉每一个奇数位的正数,不会影响前面的数
如果删掉位置 2 2 2 的数,那么后面所有的正数都可以被删掉
接下来只要特判位置 1 1 1 和位置 2 2 2 的数,取 m a x max max 即可
ll solve() {
int n; cin >> n;
ll res = 0;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
if (i >= 3 && a[i] > 0) res += a[i];
}
res += max(0, a[1] + (n > 1) * max(0, a[2]));
return res;
}
题意 给定一棵树,节点编号为 1 ∼ n 1\sim n 1∼n,点权分别为 a i a_i ai
给定操作:选定点 r r r 和数值 c c c,将 r r r 子树所有节点(包括 r r r)都异或上 c c c,代价为 r r r 子树大小与 c c c 的乘积
对于树根为 1 , 2 , . . . , n 1,2,...,n 1,2,...,n 时,使得数中的点权值全部相等,花费的最小代价
题解 考虑树根为 1 1 1 的情况,分治思想,从叶子节点往上回溯处理,每次将子节点全部异或上一个值使得与父节点相等。因为两个节点间和菊花图都只有一种情况,因此回溯上去的结果也只有一种情况,由于异或顺序时可以调换的,所以所有乱序的操作,都可以排序成回溯操作,因此有且只有一种情况能够使得所有操作后,所有点权相等
对于节点 v v v,它的父节点为 u u u,此时已经保证了 v v v 的所有子节点的点权都等于 v v v 的点权,由于有 a v ⊕ c = a u a_v\oplus c=a_u av⊕c=au,故 c = a u ⊕ a v c=a_u\oplus a_v c=au⊕av。由于在叶节点,所有子节点的点权已相等(只有一个点),故此分治是合法的
故树根为 1 1 1 的代价为 $\sum size_v\times (a_v\oplus a_u) \$
接下来进行换根操作:
当将根由 u u u 换成其子节点 v v v,对于 v v v 的所有节点,无需再进行异或操作,故代价减小 s i z e v × ( a v ⊕ a u ) size_v\times (a_v\oplus a_u) sizev×(av⊕au),但需要对 u u u 这一子树的所有节点进行异或操作,代价增加 ( n − s i z e v ) × ( a v ⊕ a u ) (n-size_v)\times (a_v\oplus a_u) (n−sizev)×(av⊕au)
则 a n s v = a n s u + ( n − 2 × s i z e v ) × ( a v ⊕ a u ) ans_v=ans_u+(n-2\times size_v)\times (a_v\oplus a_u) ansv=ansu+(n−2×sizev)×(av⊕au)
void solve() {
int n; cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i ++) cin >> a[i];
vector<vector<int>> e(n + 1);
for (int i = 1; i < n; i ++) {
int u, v; cin >> u >> v;
e[u].push_back(v), e[v].push_back(u);
}
vector<ll> sz(n + 1, 1), ans(n + 1);
function<void(int, int)> dfs = [&](int u, int fa) {
for (auto v : e[u]) {
if (v == fa) continue;
dfs(v, u);
sz[u] += sz[v];
ans[1] += (a[u] ^ a[v]) * sz[v];
}
};
dfs(1, 1);
function<void(int, int)> dfs2 = [&](int u, int fa) {
for (auto v : e[u]) {
if (v == fa) continue;
ans[v] = ans[u] + (a[u] ^ a[v]) * (n - sz[v] * 2);
dfs2(v, u);
}
};
dfs2(1, 1);
for (int i = 1; i <= n; i ++) cout << ans[i] << ' ';
cout << endl;
}