传送门

题面

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. 获取一组radio按钮选中的值Value

    1.效果 2.HTML代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind=" ...

  2. 九度OJ 1100:最短路径 (最短路径)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4185 解决:619 题目描述: N个城市,标号从0到N-1,M条道路,第K条道路(K从0开始)的长度为2^K,求编号为0的城市到其他城市的 ...

  3. Win32对话框工程笔记

    Main.cpp #include <Windows.h> #include "resource.h" INT_PTR CALLBACK dialogProc(HWND ...

  4. windows搭建FTP服务器实战

    第一步:创建用户名密码(ftp使用) 1.1.点击“开始”菜单,选择“控制面板”. 1.2.选择“管理工具”—>“计算机管理” 1.3. 选择“本地用户和组”下的用户,右键选择“新用户” 输入用 ...

  5. Visitor Pattern

    1.Visitor模式:将更新(变更)封装到一个类中(访问操作),并由待更改类提供一个接收接口,则可在不破坏类的前提下,为类提供增加新的新操作. 2.Visitor模式结构图 Visitor模式的关键 ...

  6. volley get post json imagerequest imageloader networkimageview 加载网络本地图片

    官方网站  https://www.androidhive.info/2014/05/android-working-with-volley-library-1/ private void initL ...

  7. delphi如何让程序最小化到任务栏(使用Shell_NotifyIcon API函数)

    现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标.象FoxMail 3.0 NetVampire 3.0等都提供了这样的功 ...

  8. Juery插件-- jquery.cookie.js

    1.引入jquery <script src="scripts/jquery-1.8.8.js" type="text/javascript">&l ...

  9. C++中如何计算程序运行的时间 (转载)

    转载地址:http://blog.csdn.net/wuxuguang123/article/details/8130081 一 个程序的功能通常有很多种方法来实现,怎么样的程序才算得上最优呢?举个例 ...

  10. Codeforces Round #374 (Div. 2) D. Maxim and Array —— 贪心

    题目链接:http://codeforces.com/problemset/problem/721/D D. Maxim and Array time limit per test 2 seconds ...