T1:
直接rand,没分
T2:
考场上理解错题意了,以为一定要数字一一对应,并且它的子树可以只是一部分,然后就弄出了一个算法
用f[x]表示有x的情况下,x与x子树一部分的方案数
fg[x]表示x是否满足匹配
那么如果左边的点是一样的,那么左边的匹配关系可以上穿
右边同理;
只有两边都一样,并且都匹配了,才可以继续上传
于是得到:
void dfs(int x) { if(!la[x]&&!ra[x]) { if(!lb[x]&&!rb[x]) { f[x]=1; fg[x]=1; } return ; } if(la[x]) dfs(la[x]); if(ra[x]) dfs(ra[x]); if(la[x]==lb[x]) f[x]+=f[la[x]]; if(ra[x]==rb[x]) f[x]+=f[ra[x]]; if(la[x]==lb[x]&&ra[x]==rb[x]&&fg[la[x]]&&fg[ra[x]]) { f[x]++; fg[x]=1; } }
然后,居然能过样例,交上去,当然爆0了
考后,才发现它只要形状一样就行了,不用数字也一样,而且不用整颗子树
我们可以用hash来确定树的形状
我们发现,只要把左边hash进去,右边hash进去就可以确定形状了
为了让初值不是0,我们把sz也hash进去了
所以我们可以得到一个hash函数:
hsh[x]=hsh[l[x]]*p1+hsh[r[x]]*p2+sz[x]*p3
然后,交上去,wa35
没事,只有把hash函数改的更玄学就行了
所以,hsh[x]=(hsh[l[x]] xor p3)*p1+(hsh[r[x]] xor p3)*p2+sz[x]*p3
然后就是常规的hash表操作
T3:
洛谷P3469 https://www.luogu.com.cn/problem/P3469
详细分析可以看我的博客: https://www.cnblogs.com/shenbear/p/12228003.html