E. Wooden Game

E. Wooden Game

You are given a forest of k 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 v is the set of vertices for which v lies on the shortest path from this vertex to the root, including v itself.

Input

Each test consists of multiple test cases. The first line contains an integer t (1t104) — the number of test cases. Then follows the description of the test cases.

The first line of each test case contains a single integer k (1k106) — the number of trees in the forest.

This is followed by a description of each of the k trees:

The first line contains a single integer n (1n106) — the size of the tree. The vertices of the tree are numbered with integers from 1 to n. The root of the tree is vertex number 1.

The second line contains n1 integers p2,p3,pn (1pi<i), where pi — the parent of vertex i.

It is guaranteed that the sum of k and n for all sets of input data does not exceed 106.

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 4 from the first tree.

The third operation removes the first tree. The result is 6|1|3=7 (| denotes bitwise OR).

In the third test case, the entire tree needs to be removed.

 

解题思路

  假设只有一棵树,那么 OR 的最大值就是这棵树本身的大小 n。假设把一棵树拆分成了 m 个部分,每个部分的大小为 ai,有 a1a2ama1+a2++an=n,这是因为 OR 运算没有进位。另外,对于一棵大小为 n 的树,我们可以拆分得到大小在 1n 的任意一棵树,每次只需删除叶子即可。因此如果我们想让某棵树贡献某个值时,只需通过删除叶子来得到该大小的树即可,而无需考虑如何拆分。

  因此现在的问题变成了,有 k 个数,每个数可取的范围是 [1,ni],求这 k 个数 OR 的最大值。

  从高位往低位贪心考虑,对于某个位 i,如果至少有两个数的第 i 位是 1,则将其中一个数变小,使其第 0 到第 i1 位变成 1,这样通过 OR 就可以对答案贡献 2i+11。如果只有一个数的第 i 位是 1,则保留这一位,对答案贡献 2i

  AC 代码如下,时间复杂度为 O(nlogn)

#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

posted @   onlyblues  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-07-20 宠物小精灵之收服
2022-07-20 传纸条
2021-07-20 快速选择算法(找到第k个数字)
Web Analytics
点击右上角即可分享
微信分享提示