Problem Statement

We have a rooted tree with $N$ vertices numbered $1,2,\dots,N$.

The tree is rooted at Vertex $1$, and the parent of Vertex $i \ge 2$ is Vertex $P_i(<i)$.

For each integer $k=1,2,\dots,N$, solve the following problem:

There are $2^{k-1}$ ways to choose some of the vertices numbered between $1$ and $k$ so that Vertex $1$ is chosen.

How many of them satisfy the following condition: the subgraph induced by the set of chosen vertices forms a perfect binary tree (with $2^d-1$ vertices for a positive integer $d$) rooted at Vertex $1$?

Since the count may be enormous, print the count modulo $998244353$.

What is an induced subgraph?

Let $S$ be a subset of the vertex set of a graph $G$. The subgraph $H$ induced by this vertex set $S$ is constructed as follows:

  • Let the vertex set of $H$ equal $S$.
  • Then, we add edges to $H$ as follows:
    • For all vertex pairs $(i, j)$ such that $i,j \in S, i < j$, if there is an edge connecting $i$ and $j$ in $G$, then add an edge connecting $i$ and $j$ to $H$.
What is a perfect binary tree?

A perfect binary tree is a rooted tree that satisfies all of the following conditions:

  • Every vertex that is not a leaf has exactly $2$ children.
  • All leaves have the same distance from the root.

Here, we regard a graph with \(1\) vertex and \(0\) edges as a perfect binary tree, too.

Constraints

  • All values in input are integers.
  • $1 \le N \le 3 \times 10^5$
  • $1 \le P_i < i$

Input

Input is given from Standard Input in the following format:

$N$
$P_2$ $P_3$ $\dots$ $P_N$

Output

Print $N$ lines.
The $i$-th ($1 \le i \le N$) line should contain the answer as an integer when $k=i$.


Sample Input 1

10
1 1 2 1 2 5 5 5 1

Sample Output 1

1
1
2
2
4
4
4
5
7
10

The following ways of choosing vertices should be counted:

  • $\{1\}$ when $k \ge 1$
  • $\{1,2,3\}$ when $k \ge 3$
  • $\{1,2,5\},\{1,3,5\}$ when $k \ge 5$
  • $\{1,2,4,5,6,7,8\}$ when $k \ge 8$
  • $\{1,2,4,5,6,7,9\},\{1,2,4,5,6,8,9\}$ when $k \ge 9$
  • $\{1,2,10\},\{1,3,10\},\{1,5,10\}$ when $k = 10$

Sample Input 2

1

Sample Output 2

1

If $N=1$, the $2$-nd line of the Input is empty.


Sample Input 3

10
1 2 3 4 5 6 7 8 9

Sample Output 3

1
1
1
1
1
1
1
1
1
1

Sample Input 4

13
1 1 1 2 2 2 3 3 3 4 4 4

Sample Output 4

1
1
2
4
4
4
4
4
7
13
13
19
31

先考虑如果不带实时询问怎么做?定义 \(dp_{i,j}\) 为以 \(i\) 为节点,深度为 \(j\) 的导出完全二叉树有多少个。发现 \(j\) 是 \(logn\) 级别的,因为一个 \(j\) 层完全二叉树的节点数量是 \(2^j\) 级别,而节点数量要 \(\le n\)。

用 \(son\) 表示 \(i\) 的所有儿子的集合, 初始化 \(dp_{i,0}=1\)$$dp_{i,j}=\sum\limits_{v1\in son}\sum\limits_{v2>v1,v2\in son}dp_{v1,j-1}\times dp_{v2,j-1}$$

这个可以化简为 $$(\sum\limits_{v\in son}dp_{v,j-1})^2-\sum\limits_{v\in son}dp_{v,j-1}^2$$

这个东西就可以实现树上 \(O(1)\) 转移了,最终答案为 \(\sum\limits_{j=0}^{logn}dp_{1,j}\),总复杂度 \(O(nlogn)\)

现在要求加点,询问。那么思路很简单,首先如果一个点的层数大过 \(logn\),他影响不到答案。然后考虑不断往上爬,去更改会改变的答案。

要直接维护 \(dp\) 值不容易,考虑维护所有 \(dp\) 值的和还有平方和,有这两个更改我们可以推出 \(dp\) 值的更改。然后发现,如果现在加入点 \(x\) 的时候,点 \(y\) 与点 \(x\) 的层数差为 \(a\),那么只有 \(dp_{y,a}\) 有可能更改,加上 \(x\) 的层数 \(\le logn\),所以这样子改的复杂度是 \(O(logn)\) 的。具体更改时就是减去旧的加上新的就行了。

#include<cstdio>
const int N=3e5+5,P=998244353,inv2=499122177;
typedef long long LL;
long long s[N][25],f[N][25],dp[N][25],ans,dep[N];//s表示和,f表示平方和
int n,k,fa[N];
void dfs(int x,int y,LL a,LL b)//a表示原来的,b表示新的
{
LL k=dp[x][y];
(s[x][y]+=b-a+P)%=P;
(f[x][y]+=b*b%P-a*a%P+P)%=P;
dp[x][y]=(s[x][y]*s[x][y]%P-f[x][y]+P)*inv2%P;
if(x-1)
dfs(fa[x],y+1,k,dp[x][y]);
}
int main()
{
scanf("%d",&n);
dp[1][0]=1;
puts("1");
for(int i=2;i<=n;i++)
{
scanf("%d",fa+i),dep[i]=dep[fa[i]]+1;
f[i][0]=dp[i][0]=s[i][0]=1;
if(dep[i]<=20)
dfs(fa[i],1,0,1);
// puts("qzmakioi");
ans=0;
for(int j=0;j<=20;j++)
(ans+=dp[1][j])%=P;
printf("%lld\n",ans);
}
}

[ABC264Ex] Perfect Binary Tree的更多相关文章

  1. Types of Binary Tree

    Complete Binary Tree According to wiki, A complete binary tree is a binary tree in which every level ...

  2. BFS广度优先 vs DFS深度优先 for Binary Tree

    https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/ What are BFS and DFS for Binary Tree? A Tree i ...

  3. [LeetCode] 543. Diameter of Binary Tree 二叉树的直径

    Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a b ...

  4. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  5. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  6. Leetcode, construct binary tree from inorder and post order traversal

    Sept. 13, 2015 Spent more than a few hours to work on the leetcode problem, and my favorite blogs ab ...

  7. [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  8. [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化

    One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...

  9. [LeetCode] Binary Tree Vertical Order Traversal 二叉树的竖直遍历

    Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...

  10. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

随机推荐

  1. 【JMeter】常用线程组设置策略

    常用线程组设置策略 目录 常用线程组设置策略 一.前言 二.单场景基准测试 1.介绍 2.线程组设计 3.测试结果 三.单场景并发测试 1.介绍 2.线程组设计 3.测试结果 四.单场景容量/爬坡测试 ...

  2. 在微服务环境下,远程调用feign和异步线程存在请求数据丢失问题

    一.无异步线程得情况下feign远程调用: 0.登录拦截器: @Component public class LoginUserInterceptor implements HandlerInterc ...

  3. 4.1 应用层Hook挂钩原理分析

    InlineHook 是一种计算机安全编程技术,其原理是在计算机程序执行期间进行拦截.修改.增强现有函数功能.它使用钩子函数(也可以称为回调函数)来截获程序执行的各种事件,并在事件发生前或后进行自定义 ...

  4. 音频格式轻松转 - foobar2000

    一.foobar2000简介 foobar2000 是一款免费的专业级别音频解码播放器,支持的诸多音频格式,可加载附加组件扩展更多支持. 除了解码以外,可轻松实现对音频格式的转换,支持几乎所有主流格式 ...

  5. 其它——paramiko模块的使用

    文章目录 paramiko 一 介绍 二 通过用户名密码方式远程执行命令 三 通过用户名密码方式上传下载文件 四 通过公钥私钥远程执行命令 五 通过公钥私钥远程上传下载文件 六 通过私钥字符串远程连接 ...

  6. Flask框架——请求扩展、flask中间件、蓝图、分析线程和协程

    文章目录 01 请求扩展 01 before_first_request :项目启动后第一次请求的时候执行 02 before_request:每次请求之前执行 03 after_request:每次 ...

  7. vim vimtutor

    =============================================================================== =      歡     迎     閱 ...

  8. 采用ResNet网络+TSNE降维算法对自建图像数据集进行二维可视化显示

    起因:某一天下午,我在"玩"的时候,突然接到了老板的电话,说是要对图像做可视化降维.因此,我拿到了一批图像的数据. 数据的特点: 1.数据集的图像分为4类,并且每一种类的图像多少不 ...

  9. Python shape+size详解

    import cv2 from PIL import Image # pic.JPG 图片的路径 img = cv2.imread("pic.JPG",-1) print(&quo ...

  10. 自学一周python做的一个小游戏《大球吃小球》

    需求 1,显示一个窗口. 2,我们要做到的功能有鼠标点击屏幕生成小球. 3,生成的小球大小随机,颜色随机,向随机方向移动,速度也随机. 4,大的球碰到小球时可以吃掉小球,吃掉后会变大. 5,球碰到边界 ...