树形\(DP\)

实际上,这道题应该不是很难。

我们设\(f_{x,i,j}\)表示在以\(x\)为根的子树内,原本应输出\(i\),结果输出了\(j\)的情况数

转移时,为了方便,我们先考虑与,再考虑非,即先转移,再交换\(f_{x,0,0}\)和\(f_{x,1,1}\),\(f_{x,1,0}\)和\(f_{x,0,1}\)。

这样一来,转移方程如下:

\[f_{x,i1\&i2,j1\&j2}=\sum f_{x,i1,j1}*f_{son,i2,j2}
\]

然后,在转移结束,交换完毕之后,我们还要判断这点是否出故障。

若\(op_x=0\),我们令\(f_{x,0,0}=f_{x,0,0}+f_{x,0,1},f_{x,1,0}=f_{x,1,0}+f_{x,1,1},f_{x,0,1}=f_{x,1,1}=0\),\(op_x=1\)同理。

注意最后答案为\(\frac{f_{rt,0,0}+f_{rt,1,1}}{2^{\sum g_i}}\),且\(\sum g_i\)千万不能向\(998244353\)取模!我一开始智障地取了模,调了1个小时,最后还是左右横调才调出来的。。。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 200000
#define X 998244353
#define LL long long
#define swap(x,y) (x^=y^=x^=y)
#define Qinv(x) Qpow(x,X-2)
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,rt,ee,g[N+5],op[N+5],lnk[N+5];struct edge {int to,nxt;}e[N];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int f;char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0,f=1;W(!D) f=c^'-'?1:-1;W(x=tn+(c&15),D);x*=f;}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
#undef D
}F;
class TreeDper//树形DP
{
private:
int Sz[N+5],f[N+5][2][2],f_[2][2];
I int Qpow(RI x,LL y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}//快速幂
I void Init(CI x)//初始化,将g[i]减去已有子节点个数
{
for(RI i=(Sz[x]=0,lnk[x]);i;i=e[i].nxt) Init(e[i].to),++Sz[x];
g[x]-=Sz[x];
}
I void DP(CI x)//树形DP
{
if(!lnk[x]) return (void)(f[x][0][~op[x]?op[x]:0]=1,f[x][1][~op[x]?op[x]:1]=Qpow(2,g[x])-1);//特殊处理叶节点
RI i,xx,xy,yx,yy;for(f[x][0][0]=Qpow(2,g[x])-1,f[x][1][1]=1,i=lnk[x];i;i=e[i].nxt)//枚举子节点
{
DP(e[i].to),f_[0][0]=f_[0][1]=f_[1][0]=f_[1][1]=0;//注意此处要开一个中间数组
for(xx=0;xx^2;++xx) for(xy=0;xy^2;++xy) for(yx=0;yx^2;++yx) for(yy=0;yy^2;++yy)
f_[xx&yx][xy&yy]=(1LL*f[x][xx][xy]*f[e[i].to][yx][yy]+f_[xx&yx][xy&yy])%X;//转移
f[x][0][0]=f_[0][0],f[x][0][1]=f_[0][1],f[x][1][0]=f_[1][0],f[x][1][1]=f_[1][1];//更新信息
}
swap(f[x][0][0],f[x][1][1]),swap(f[x][0][1],f[x][1][0]),//交换
op[x]==0&&(Inc(f[x][0][0],f[x][0][1]),Inc(f[x][1][0],f[x][1][1]),f[x][0][1]=f[x][1][1]=0),//特判op[x]=0
op[x]==1&&(Inc(f[x][1][1],f[x][1][0]),Inc(f[x][0][1],f[x][0][0]),f[x][1][0]=f[x][0][0]=0);//特判op[x]=1
}
public:
I void Solve()
{
RI i;LL sg=0;for(Init(rt),i=1;i<=n;++i) sg+=g[i];DP(rt);//统计Σg[i]
printf("%d",1LL*(f[rt][0][0]+f[rt][1][1])*Qinv(Qpow(2,sg))%X);//输出答案
}
}D;
int main()
{
freopen("nand.in","r",stdin),freopen("nand.out","w",stdout);
RI i,x;for(F.read(n),i=1;i<=n;++i) F.read(x,g[i],op[i]),x?add(x,i):rt=i;//读入数据
return D.Solve(),0;
}

【2019.7.15 NOIP模拟赛 T2】与非树(nand)(树形DP)的更多相关文章

  1. 【2019.8.15 慈溪模拟赛 T2】组合数(binom)(卢卡斯定理+高维前缀和)

    卢卡斯定理 题目中说到\(p\)是质数. 而此时要求组合数向质数取模的结果,就可以用卢卡斯定理: \[C_x^y=C_{x\ div\ p}^{y\ div\ p}\cdot C_{x\ mod\ p ...

  2. 【2019.7.15 NOIP模拟赛 T1】夹缝(mirror)(思维题)

    思维题 此题应该是比较偏思维的. 假设一次反射后前进的距离是\(2^x(2y+1)\),则显然,它可以看做是前进距离为\(2^x\)的光线经过了\((2y+1)\)次反射,两者是等价的,甚至后者可能还 ...

  3. 【2019.8.20 NOIP模拟赛 T2】小B的树(tree)(树形DP)

    树形\(DP\) 考虑设\(f_{i,j,k}\)表示在\(i\)的子树内,从\(i\)向下的最长链长度为\(j\),\(i\)子树内直径长度为\(k\)的概率. 然后我们就能发现这个东西直接转移是几 ...

  4. 【2019.7.20 NOIP模拟赛 T2】B(B)(数位DP)

    数位\(DP\) 首先考虑二进制数\(G(i)\)的一些性质: \(G(i)\)不可能有连续两位第\(x\)位和第\(x+1\)位都是\(1\).因为这样就可以进位到第\(x+2\)位.其余情况下,这 ...

  5. 【2019.7.16 NOIP模拟赛 T2】折叠(fold)(动态规划)

    暴力\(DP\) 考虑暴力\(DP\),我们设\(f_{i,j}\)表示当前覆盖长度为\(i\),上一次折叠长度为\(j\)的方案数. 转移时需要再枚举这次的折叠长度\(k\)(\(k\ge j\)) ...

  6. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  7. 2019.7.26 NOIP 模拟赛

    这次模拟赛真的,,卡常赛. The solution of T1: std是打表,,考场上sb想自己改进匈牙利然后wei了(好像匈牙利是错的. 大力剪枝搜索.代码不放了. 这是什么神仙D1T1,爆蛋T ...

  8. 2019.03.15 ZJOI2019模拟赛 解题报告

    得分: \(20+45+15=80\)(三题暴力全写挂...) \(T1\):Lyk Love painting 首先,不难想到二分答案然后\(DP\)验证. 设当前需验证的答案为\(x\),则一个暴 ...

  9. 【2019.8.15 慈溪模拟赛 T1】插头(plugin)(二分+贪心)

    二分 首先,可以发现,最后的答案显然满足可二分性,因此我们可以二分答案. 然后,我们只要贪心,就可以验证了. 贪心 不难发现,肯定会优先选择能提供更多插座的排插,且在确定充电器个数的情况下,肯定选择能 ...

随机推荐

  1. (二十五)golang--数组

    数组:存放多个同一类型的数据.在Go中,数组也是一种值类型数组的基本定义: 数组的内存布局: 数组的地址可以用&取出,且它的地址就是第一个元素的地址 数组不用被被初始化而默认是有值的: 数组中 ...

  2. eclipse快速给表达式生成对应变量的快捷键

    这里记录下在Eclipse中快速给表达式生成对应变量的快捷键,有两种方式. [Ctrl + 2] 光标放在该表达式行的任意位置,按[Ctrl+2],会弹出提示,根据提示选择[F/L/R],就会自动生成 ...

  3. [Docker] Win10中安装Docker并运行Nginx镜像

    一.安装Docker 进入官网:https://www.docker.com/products/docker-desktop 可能需要先注册登录,很简单的. 点击 Download Desktop f ...

  4. MySQL分析数据运行状态利器【show full processlist】

    原文地址:https://www.cnblogs.com/shihuc/p/8733460.html 今天的主角是: SHOW [FULL] PROCESSLIST show full process ...

  5. java架构之路-(nginx使用详解)nginx的安装和基本配置

    Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和Unix的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的Unix工具软件.应用程序和网络协议.它支持32位 ...

  6. Kafka Network层解析,还是有人把它说清楚了

    我们知道kafka是基于TCP连接的.其并没有像很多中间件使用netty作为TCP服务器.而是自己基于Java NIO写了一套. 几个重要类 先看下Kafka Client的网络层架构. 本文主要分析 ...

  7. ASP.NET Core MVC 过滤器

    参考网址:https://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-4_4_3-filters.html ASP.NET Core有五种类型的过滤器,每个过滤 ...

  8. MES系统如何帮助烟草行业管理生产流程

    与很多其他行业一样,烟草MES系统可以帮助卷烟企业实现智能生产.精益制造.快速实现烟草企业数字化车间的创建,助力企业实现改造升级,从而提升企业生产效率,降低生产成产.烟草行业得MES者得天下. 烟草行 ...

  9. 如何只修改EFLAGS寄存器中一个标志位的值?

    版权声明:本文为博主原创文章,2019-08-23,22:21:42转载请附上原文出处链接和本声明.作者By-----溺心与沉浮----博客园   1.写汇编指令只影响CF位的值(不能影响其他标志位 ...

  10. 数字,字符串,time模块,文本进度条

    数字和字符串 数字类型 整形 整数, 1/2/3/12/2019 整形用来描述什么, 身高/年龄/体重 age = 18 height = 180 浮点型 浮点数,小数 salary = 10 pri ...