传送门

题面

liu_runda曾经是个喜欢切数数题的OIer,往往看到数数题他就开始刚数数题.于是liu_runda出了一个数树题.听说OI圈子珂学盛行,他就在题目名字里加了珂学二字.一开始liu_runda想让选手数n个节点的不同构的二叉树的数目.

但是liu_runda虽然退役已久,也知道答案就是Catalan(n),这太裸了,出出来一定会被挂起来裱.因此他把题目加强.我们从二叉树的根节点出发一直向右儿子走到不能再走为止,可以找到最右下方的节点v,这个节点是没有右儿子的.

如果根节点和v不相同,我们就把根节点和根节点的右儿子断开,让根节点的右儿子成为新的根节点,同时把根节点接在v的右儿子位置.根节点的左儿子此时仍然挂在根节点上.

这样的操作可以进行多次.如果两棵二叉树能通过若干次这样的操作变得同构,我们也认为它们是同构的.

问在这种新的定义下有多少n个节点的本质不同的二叉树.答案可能很大,所以只需要输出对998244353取模后的结果.

题解

全场切就我一个不会的……话说我对\(burnside\)理解还是太浅啊……

我们对于一棵二叉树定义一个括号表示法,其中第一个左括号和第一个右括号之间的是根节点的左子树,后面的全都是根节点的右子树。如果某一对匹配的括号满足不存在其他匹配的括号包含它们,我们就称其为“顶级括号”。

从二叉树的根节点出发向右儿子方向一直走到没有右儿子时,经过的一条链我们不妨称作“右侧链”。根据刚刚的定义,每个顶级括号都对应右侧链上的一个节点。而每个顶级括号内部的串对应这个节点的左子树。

这样的话\(n\)个节点的二叉树就可以用\(n\)个左括号和\(n\)个右括号组成的合法的括号序列来表示了,可以转化为数“循环移位后相同则本质相同”的括号序列个数

这里有个小问题,比如\((())\)移位后变成\()(()\),后者不合法,说明这个交换群不满足封闭性

于是这里有个结论:\(n\)个\(0\),\(n\)个\(1\)的\(01\)序列“循环移位后相同则本质相同”的等价类个数和\(n\)对合法括号序列的等价类一一对应

显然每个合法的括号序列都可以转化为\(01\)序列。而对于每个\(01\)序列,都可以经过若干次循环移位后得到一个“任意前缀中\(0\)的个数不少于\(1\)”的序列,就可以把它转化为一个合法的括号序列

所以现在只要数\(01\)序列的不同等价类个数就好了。根据\(burnside\)引理,等价类个数为不动点总数的平均值。

往右旋转\(0\)次不变,每个点都不变,不动点个数为\({2n\choose n}\)

往右旋转\(1\)次不变,需要任意两个相邻位置颜色相等,不存在

往右旋转\(2\)次不变,那么奇数位置都相同,偶数位置都相同,有2种

往右旋转\(m\)次不变,那么记\(G=\gcd(2n,m),G,2G,3G…\)这些位置都相同,\(1,G+1,2G+1…\)这些位置都相同,因此我们只需要考虑前\(G\)个位置如何排列。只有当\(G\)为偶数的时候有\({G\choose G/2}\)个不动点

于是就可以做到\(O(n\log n)\)计算了,其中\(\log\)是计算\(\gcd\)的复杂度(也可以直接\(O(n)\)预处理欧拉函数然后搞,不过懒了2333)

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=2e6+5,P=998244353;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int fac[N],inv[N],n,res,lim,g;
inline int C(R int n,R int m){if(m>n)return 0;return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
inline int gcd(R int x,R int y){if(!y)return x;while(y^=x^=y^=x%=y);return x;}
int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%d",&n),lim=n<<1;
fac[0]=inv[0]=1;fp(i,1,lim)fac[i]=mul(fac[i-1],i);
inv[lim]=ksm(fac[lim],P-2);fd(i,lim-1,1)inv[i]=mul(inv[i+1],i+1);
for(R int i=0;i<=lim-1;i+=2)g=gcd(lim,i),res=add(res,C(g,g/2));
printf("%d\n",mul(res,ksm(lim,P-2)));return 0;
}

jzoj5988. 【WC2019模拟2019.1.4】珂学计树题 (burnside引理)的更多相关文章

  1. JZOJ 5988 珂学计树题 (Burnside引理)

    什么神题a-没学过Burnside引理a学了也做不来系列-考场没怎么看这题,上最后十分钟打了样例就溜了-然后这题爆0了. Here CODE #include <cctype> #incl ...

  2. JZOJ5988 珂学计树题

    题意 liu_runda曾经是个喜欢切数数题的OIer,往往看到数数题他就开始刚数数题.于是liu_runda出了一个数树题.听说OI圈子珂学盛行,他就在题目名字里加了珂学二字.一开始liu_rund ...

  3. jzoj5987. 【WC2019模拟2019.1.4】仙人掌毒题 (树链剖分+概率期望+容斥)

    题面 题解 又一道全场切的题目我连题目都没看懂--细节真多-- 先考虑怎么维护仙人掌.在线可以用LCT,或者像我代码里先离线,并按时间求出一棵最小生成树(或者一个森林),然后树链剖分.如果一条边不是生 ...

  4. jzoj5986. 【WC2019模拟2019.1.4】立体几何题 (权值线段树)

    传送门 题面 题解 不难看出每个点的大小为行列限制中较小的那一个(因为数据保证有解) 对于行的每个限制,能取到的个数是列里限制大于等于它的数的个数,同理,对于列是行里大于它的个数(这里没有等于,为了避 ...

  5. 6359. 【NOIP2019模拟2019.9.15】小ω的树(tree)(定期重构)

    题目描述 题解 qy的毒瘤题 CSP搞这种码农题当场手撕出题人 先按照边权从大到小建重构树,然后40%暴力修改+查找即可 100%可以定期重构+平衡规划,每次把B个询问拉出来建虚树,在虚树上暴力维护每 ...

  6. [JZOJ6359] 【NOIP2019模拟2019.9.15】小ω的树

    题目 题目大意 给你一棵树,带点权和边权. 要你选择一个联通子图,使得点权和乘最小边权最大. 支持修改点权操作. 思考历程 显然,最先想到的当然是重构树了-- 重构树就是在做最大生成树的时候,当两个联 ...

  7. CF896C Willem, Chtholly and Seniorious(珂朵莉树)

    中文题面 珂朵莉树的板子……这篇文章很不错 据说还有奈芙莲树和瑟尼欧里斯树…… 等联赛考完去学一下(逃 //minamoto #include<bits/stdc++.h> #define ...

  8. 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树

    正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...

  9. 「学习笔记」珂朵莉树 ODT

    珂朵莉树,也叫ODT(Old Driver Tree 老司机树) 从前有一天,珂朵莉出现了... 然后有一天,珂朵莉树出现了... 看看图片的地址 Codeforces可还行) 没错,珂朵莉树来自Co ...

随机推荐

  1. iOS开发中的单元测试(三)——URLManager中的测试用例解析

    本文转载至 http://www.cocoachina.com/cms/plus/view.php?aid=8088   此前,我们在<iOS开发中的单元测试(一)&(二)>中介绍 ...

  2. undefined reference to '__android_log_print'解决方案

    1:在源程序中添加头文件 #include <cutils/log.h> 2:在Android.mk中添加 LOCAL_SHARED_LIBRARIES := \ libutils \ l ...

  3. MotionEvent分析及ImageView缩放实现

    这个类在各种View和用户的手势操作之间的交互存在很大的自定义空间.要理解清楚这个类的一些特性和意义,对自定义的新型控件很有帮助 先翻译一下开发者文档的描述 Overview Motion event ...

  4. 一套完整的前台页面增删改查以及js(easyui)

    增加页面: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnc ...

  5. powershell 扩展 (PSCX) 安装指南

    在玩ansible的过程中,使用win_unzip模块时powershell支持不了,需要安装PSCX对powershell进行扩展,随手记录下安装过程. 从官网下载的Pscx是一个zip压缩文件,解 ...

  6. 使用geolocation

    The geolocation object geolocation API建立在navigator.geolocation 上. 如果对象存在,才可以使用定位服务. if ("geoloc ...

  7. css绘制三角形

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 【C】貌似不友好的scanf()

    scanf语句执行过程: (1)逆序取参数的偏移地址并分别入栈. (2)根据控制字符串的格式说明符从缓冲区取数据给各变量赋值. ①若格式说明符是数值类数据:如果从缓冲区中拿出的第一个字符可以合法表示该 ...

  9. HDU2147 kiki's game (SG表找规律)

    Recently kiki has nothing to do. While she is bored, an idea appears in his mind, she just playes th ...

  10. Win10设置vs2010总是以管理员身份运行

    有的项目用vs打开后直接运行总是要求提升权限,如下图       1.第一步(这样的方式只能是先运行vs,然后再打开项目,这样才是以管理员的身份运行的.但是如果是通过sln文件的快捷方式打开的,却不是 ...