E. Wooden Game
E. Wooden Game
You are given a forest of rooted trees. Lumberjack Timofey wants to cut down the entire forest by applying the following operation:
- Select a subtree of any vertex of one of the trees and remove it from the tree.
Timofey loves bitwise operations, so he wants the bitwise OR of the sizes of the subtrees he removed to be maximum. Help him and find the maximum result he can obtain.
A tree is a connected graph without cycles, loops, or multiple edges. In a rooted tree, a selected vertex is called a root. A forest is a collection of one or more trees.
The subtree of a vertex is the set of vertices for which lies on the shortest path from this vertex to the root, including itself.
Input
Each test consists of multiple test cases. The first line contains an integer () — the number of test cases. Then follows the description of the test cases.
The first line of each test case contains a single integer () — the number of trees in the forest.
This is followed by a description of each of the trees:
The first line contains a single integer () — the size of the tree. The vertices of the tree are numbered with integers from to . The root of the tree is vertex number .
The second line contains integers (), where — the parent of vertex .
It is guaranteed that the sum of and for all sets of input data does not exceed .
Output
For each test case, output a single integer — the maximum result that can be obtained.
Example
input
3
1
1
2
4
1 2 2
6
1 1 3 1 3
1
10
1 2 2 1 1 5 7 6 4
output
1
7
10
Note
In the second test case, the trees look like this:
The first operation removes the entire second tree.
The second operation removes vertex from the first tree.
The third operation removes the first tree. The result is ( denotes bitwise OR).
In the third test case, the entire tree needs to be removed.
解题思路
假设只有一棵树,那么 OR 的最大值就是这棵树本身的大小 。假设把一棵树拆分成了 个部分,每个部分的大小为 ,有 ,这是因为 OR 运算没有进位。另外,对于一棵大小为 的树,我们可以拆分得到大小在 的任意一棵树,每次只需删除叶子即可。因此如果我们想让某棵树贡献某个值时,只需通过删除叶子来得到该大小的树即可,而无需考虑如何拆分。
因此现在的问题变成了,有 个数,每个数可取的范围是 ,求这 个数 OR 的最大值。
从高位往低位贪心考虑,对于某个位 ,如果至少有两个数的第 位是 ,则将其中一个数变小,使其第 到第 位变成 ,这样通过 OR 就可以对答案贡献 。如果只有一个数的第 位是 ,则保留这一位,对答案贡献 。
AC 代码如下,时间复杂度为 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
int a[N];
void solve() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", a + i);
for (int j = 0; j < a[i] - 1; j++) {
scanf("%*d");
}
}
sort(a, a + n, greater<int>());
int ret = 0;
for (int i = 0; i < n; i++) {
for (int j = 19; j >= 0; j--) {
if (a[i] >> j & 1) {
if (ret >> j & 1) ret |= (1 << j) - 1;
else ret |= 1 << j;
}
}
}
printf("%d\n", ret);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
参考资料
Codeforces Round 959 sponsored by NEAR (Div. 1 + Div. 2) A~E:https://zhuanlan.zhihu.com/p/709662276
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/18313527
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-07-20 宠物小精灵之收服
2022-07-20 传纸条
2021-07-20 快速选择算法(找到第k个数字)