考虑令$a_{i}$为i的位置,$p_{i}=0/1$表示第i个点的贡献,那么$p_{x}=0$当且仅当存在与其相邻的点$y$满足$a_{y}<a_{x}$且$p_{y}=1$
树形dp,定义状态$g[k][j][0/1/2]$表示以$k$为根的子树中选择了j个点,$p_{k}=1$或$p_{k}=0$或还没有参与,$f[k][j][0/1/2]$表示这样的$cost$之和
暴力转移即可(转移方程详见代码),注意:1.要乘上组合数表示不同子树之间的顺序;2.要另开一个数组来讨论;3.讨论时要对儿子和根的位置关系分类

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 2005
4 #define mod 998244353
5 struct ji{
6 int nex,to;
7 }edge[N];
8 int E,t,n,x,fac[N],inv[N],head[N],sz[N],g[N][N][3],f[N][N][3];
9 int c(int n,int m){
10 return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;
11 }
12 void add(int x,int y){
13 edge[E].nex=head[x];
14 edge[E].to=y;
15 head[x]=E++;
16 }
17 void dfs(int k){
18 sz[k]=g[k][0][0]=g[k][0][2]=1;
19 for(int i=head[k];i!=-1;i=edge[i].nex){
20 int u=edge[i].to;
21 dfs(u);
22 for(int j=1;j<sz[u];j++)
23 for(int p=0;p<3;p++){
24 g[u][j][p]=(g[u][j][p]+g[u][j-1][p])%mod;
25 f[u][j][p]=(f[u][j][p]+f[u][j-1][p])%mod;
26 }
27 for(int j=0;j<sz[k];j++)
28 for(int jj=0;jj<=sz[u];jj++){
29 int C=1LL*c(j+jj,j)*c(sz[k]-j-1+sz[u]-jj,sz[u]-jj)%mod;
30 for(int p1=0;p1<3;p1++)
31 for(int p2=0;p2<3;p2++){
32 int s1=0,s2=0;
33 if (jj){
34 s1=1LL*g[u][jj-1][p2]*g[k][j][p1]%mod*C%mod;
35 s2=(1LL*g[u][jj-1][p2]*f[k][j][p1]+1LL*f[u][jj-1][p2]*g[k][j][p1])%mod*C%mod;
36 }
37 if ((p1==0)&&(p2==1)){
38 g[0][j+jj][0]=(g[0][j+jj][0]+s1)%mod;
39 f[0][j+jj][0]=(f[0][j+jj][0]+s2)%mod;
40 }
41 if ((p1==1)&&(p2<2)||(p1==2)&&(p2==0)){
42 g[0][j+jj][1]=(g[0][j+jj][1]+s1)%mod;
43 f[0][j+jj][1]=(f[0][j+jj][1]+s2)%mod;
44 }
45 if ((p1==2)&&(p2==1)){
46 g[0][j+jj][2]=(g[0][j+jj][2]+s1)%mod;
47 f[0][j+jj][2]=(f[0][j+jj][2]+s2)%mod;
48 }
49 if (!jj)s1=g[u][sz[u]-1][p2];
50 else s1=(g[u][sz[u]-1][p2]-g[u][jj-1][p2]+mod)%mod;
51 if (!jj)s2=f[u][sz[u]-1][p2];
52 else s2=(f[u][sz[u]-1][p2]-f[u][jj-1][p2]+mod)%mod;
53 s2=(1LL*s1*f[k][j][p1]+1LL*s2*g[k][j][p1])%mod*C%mod;
54 s1=1LL*s1*g[k][j][p1]%mod*C%mod;
55 if ((p1==0)&&(p2)){
56 g[0][j+jj][0]=(g[0][j+jj][0]+s1)%mod;
57 f[0][j+jj][0]=(f[0][j+jj][0]+s2)%mod;
58 }
59 if ((p1==1)&&(p2<2)){
60 g[0][j+jj][1]=(g[0][j+jj][1]+s1)%mod;
61 f[0][j+jj][1]=(f[0][j+jj][1]+s2)%mod;
62 }
63 if ((p1==2)&&(p2<2)){
64 g[0][j+jj][2]=(g[0][j+jj][2]+s1)%mod;
65 f[0][j+jj][2]=(f[0][j+jj][2]+s2)%mod;
66 }
67 }
68 }
69 sz[k]+=sz[u];
70 for(int j=0;j<sz[k];j++)
71 for(int p=0;p<3;p++){
72 g[k][j][p]=g[0][j][p];
73 f[k][j][p]=f[0][j][p];
74 g[0][j][p]=f[0][j][p]=0;
75 }
76 }
77 for(int i=0;i<sz[k];i++)f[k][i][0]=(f[k][i][0]+g[k][i][0])%mod;
78 }
79 int main(){
80 fac[0]=inv[0]=inv[1]=1;
81 for(int i=1;i<N-4;i++)fac[i]=1LL*fac[i-1]*i%mod;
82 for(int i=2;i<N-4;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
83 for(int i=2;i<N-4;i++)inv[i]=1LL*inv[i-1]*inv[i]%mod;
84 scanf("%d",&t);
85 while (t--){
86 scanf("%d",&n);
87 E=0;
88 memset(head,-1,4*(n+1));
89 for(int i=1;i<=n;i++){
90 memset(g[i],0,sizeof(g[i]));
91 memset(f[i],0,sizeof(f[i]));
92 }
93 for(int i=2;i<=n;i++){
94 scanf("%d",&x);
95 add(x+1,i);
96 }
97 dfs(1);
98 int ans=0;
99 for(int i=0;i<n;i++)ans=(ans+0LL+f[1][i][0]+f[1][i][1])%mod;
100 printf("%d\n",ans);
101 }
102 }

[nowcoder5668J]Operating on the Tree的更多相关文章

  1. Linux and the Device Tree

    来之\kernel\Documentation\devicetree\usage-model.txt Linux and the Device Tree ----------------------- ...

  2. POJ 2420:A Star not a Tree?

    原文链接:https://www.dreamwings.cn/poj2420/2838.html A Star not a Tree? Time Limit: 1000MS   Memory Limi ...

  3. Device Tree Usage( DTS文件语法)

    http://elinux.org/Device_Tree_Usage Device Tree Usage     Top Device Tree page This page walks throu ...

  4. POJ 2420 A Star not a Tree? 爬山算法

    B - A Star not a Tree? Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...

  5. [POJ 2420] A Star not a Tree?

    A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4058   Accepted: 200 ...

  6. POJ 2420 A Star not a Tree? (计算几何-费马点)

    A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3435   Accepted: 172 ...

  7. Device Tree Usage(理解DTS文件语法)

    Basic Data Format The device tree is a simple tree structure of nodes and properties. Properties are ...

  8. How to Make a Computer Operating System

    How to Make a Computer Operating System 如何制作一个操作系统(翻译版) 原文地址:Github:How to Make a Computer Operating ...

  9. Spanning Tree Protocol (STP) in NetScaler Appliance

    Spanning Tree Protocol (STP) in NetScaler Appliance 来源 https://support.citrix.com/article/CTX112341 ...

随机推荐

  1. 洛谷2093 JZPFAR + KD-Tree学习笔记 (KD-Tree)

    KD-Tree这玩意还真的是有趣啊.... (基本完全不理解) 只能谈一点自己的对KD-Tree的了解了. 首先这个玩意就是个暴力... 他的结构有点类似二叉搜索树 每一层都是以一个维度作为划分标准. ...

  2. SpringBoot-thymeleaf-静态资源引入和接管

    引入前端 templates下放html页面 static下放css.js.image等静态资源 添加thymeleaf命名空间 <html lang="en" xmlns: ...

  3. Less-25 preg_replace2

    Less-25: 核心语句: 各种回显也均有. 通过blacklist,我们可以发现,本题屏蔽了and和or. preg_replace函数中正则表达式后面的i是一个修饰符,代表正则匹配时不区分大小写 ...

  4. [Git系列] Git 基本概念

    版本控制系统 版本控制系统是一种帮助软件开发者实现团队合作和历史版本维护的软件,一个版本控制系统应具备以下列出的这几个基本功能: 允许开发者并发工作: 不允许一个开发者覆写另一个开发者的修改: 保存所 ...

  5. [no code][scrum meeting] Alpha 8

    项目 内容 会议时间 2020-04-14 会议主题 API文档第一版交付 会议时长 30min 参会人员 PM+OCR组成员 $( "#cnblogs_post_body" ). ...

  6. 三极管和MOS管驱动电路的正确用法

    1 三极管和MOS管的基本特性 三极管是电流控制电流器件,用基极电流的变化控制集电极电流的变化.有NPN型三极管(简称P型三极管)和PNP型三极管(简称N型三极管)两种,符号如下: MOS管是电压控制 ...

  7. 最短路径算法:弗洛伊德(Floyd-Warshall)算法

    一.算法介绍 Floyd-Warshall算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存 ...

  8. 转:进行vivado开发时,Generate Bitstream报错[DRC NSTD-1],详细解决步骤

    报错如下 [Drc 23-20] Rule violation (NSTD-1) Unspecified I/O Standard - 4 out of 142 logical ports use I ...

  9. 平衡二叉树检查 牛客网 程序员面试金典 C++ Python

    平衡二叉树检查 牛客网 程序员面试金典 C++ Python 题目描述 实现一个函数,检查二叉树是否平衡,平衡的定义如下,对于树中的任意一个结点,其两颗子树的高度差不超过1. 给定指向树根结点的指针T ...

  10. 2016西邮Linux兴趣小组大事记

    2016年还有半个小时就结束了,前面把自己9月做的规划拿出来完善了下,觉得真的是不容易的一年,所有的事情只有自己经历过才会有不一样的感受,世上无难事,只怕有心人. 这是我九月份制定的计划: 下面是20 ...