两树相同的定义与题中相同,并定义两树完全相同当且仅当在不允许基环旋转的条件下相同

枚举基环的长度$l$,根据置换群的理论,答案即$\frac{1}{l}\sum_{i=1}^{l}f(i)$(其中$f(i)$表示满足"基环旋转$i$次后与原基环树完全相同"的不完全相同的树个数)

关于这个结论,考虑一棵树将基环旋转$1,2,...,l$次的$l$棵树(这$l$棵树相同),其中每一种不完全相同的树的贡献即其中与其完全相同的树个数,那么所有树总贡献即为$l$,因此除以$l$后即为答案

不难发现$f(i)$仅取决于$\gcd(l,i)$,不妨枚举后者,答案即$\frac{1}{l}\sum_{d\mid l}\varphi(\frac{l}{d})f(d)$

为了方便,我们枚举$\frac{l}{d}$,答案即$\frac{1}{l}\sum_{d\mid l}\varphi(d)f(\frac{l}{d})$

考虑$f(\frac{l}{d})$,即统计有多少组树$(T_{1},T_{2},...,T_{\frac{l}{d}})$(不允许为空),使得其点数和为$\frac{n}{d}$(若$d\not\mid n$即无解),两组树不同当且仅当满足$\exists 1\le i\le d,T_{i}$和$T'_{i}$不同

关于这个问题,显然形态和染色独立,分别考虑:

考虑$n$个点不同形态的树有多少棵,即长为$n-1$的括号序列数(注意首尾的两个括号为根,必须要匹配),也即$C_{n-1}$(其中$C_{n}$为卡特兰数第$n$项,有$C_{n}=\frac{{2n\choose n}}{n+1}$)

令$C(x)$为$C_{n-1}$的生成函数,即$C(x)=\sum_{n\ge 1}C_{n-1}x^{n}$,那么方案数即$[x^{\frac{n}{d}}]C^{\frac{l}{d}}(x)$

考虑染色数,若$\forall 1\le i\le m,d\mid a_{i}$则方案数为$\frac{\frac{n}{d}!}{\prod_{i=1}^{m}\frac{a_{i}}{d}!}$,否则为0

综上,最终答案即
$$
\sum_{l=2}^{n}\frac{1}{l}\sum_{d\mid \gcd(l,g)}\varphi(d)\cdot [x^{\frac{n}{d}}]C^{\frac{l}{d}}(x)\cdot\frac{\frac{n}{d}!}{\prod_{i=1}^{m}\frac{a_{i}}{d}!}
$$
(其中$g=\gcd(a_{1},a_{2},...,a_{m})$,显然此时$g\mid n$)

交换枚举顺序,即
$$
\left(\sum_{d\mid g}\frac{\varphi(d)}{d}\cdot \frac{\frac{n}{d}!}{\prod_{i=1}^{m}\frac{a_{i}}{d}!}\sum_{l=1}^{\frac{n}{d}}\frac{[x^{\frac{n}{d}}]C^{l}(x)}{l} \right)-C_{n-1} \frac{n!}{\prod_{i=1}^{m}a_{i}!}
$$
(注意要减去$l=1$的情况)

对于这些式子,除了$\sum_{l=1}^{\lfloor\frac{n}{d}\rfloor}\frac{[x^{\frac{n}{d}}]C^{l}(x)}{l}$都可以快速计算($\frac{\frac{n}{d}!}{\prod_{i=1}^{m}\frac{a_{i}}{d}!}$暴力即可,复杂度为$o(\sigma(g)m)$)

对于$\sum_{l=1}^{\lfloor\frac{n}{d}\rfloor}\frac{[x^{\frac{n}{d}}]C^{l}(x)}{l}$,注意到都是$[x^{\frac{n}{d}}]$,不妨先将多项式求和,即求$[x^{\frac{n}{d}}]\sum_{l=1}^{\frac{n}{d}}\frac{C^{l}(x)}{l}$

关于后者,由于$C(x)$的最低次为1,因此不妨删去$l$的上限,即求$[x^{\frac{n}{d}}]\sum_{l\ge 1}\frac{C^{l}}{l}$

关于右半部分,也即$-\ln (1-C)$,证明考虑$f(x)=\ln x$在1处的泰勒展开,即
$$
f(x)=\sum_{i\ge 0}\frac{(x-1)^{i}f^{(i)}(1)}{i!}=-\sum_{i\ge 1}\frac{(x-1)^{i}\frac{(i-1)!}{(-1)^{i}}}{i!}=-\sum_{i\ge 1}\frac{(1-x)^{i}}{i}
$$
(其中$f^{(i)}(x)$指$f$的$i$阶导数,计算并归纳可以发现其为$-\frac{(i-1)!}{(-x)^{i}}$)

不难得到$-\ln(1-C)=\sum_{i\ge 1}\frac{C^{i}(x)}{i}$,即得证

由此,多项式求对数即可,时间复杂度为$o(\sigma(g)m+n\log n)$,可以通过

事实上,令$C_{0}(x)=\frac{C(x)}{x}=\sum_{n\ge 0}C_{n}x^{n}$,那么有通项公式
$$
[x^{n}]C_{0}^{m}(x)={2n+m-1\choose n}-{2n+m-1\choose n-1}
$$

关于这个式子的解释——

$[x^{n}]C_{0}^{m}(x)$实际上可以看作从$(0,0)$走到$(2n,0)$,要求每一步从$(x,y)$到$(x+1,y\pm 1)$,求所有与$y=-1$不交的路径贡献和,其中一条路径的贡献为${tot\choose m-1}$($tot$为该路径除起点和终点外与$x$轴的交点数)

事实上,这也等价于从$(0,0)$走到$(2n+m-1,1-m)$且与$y=-m$不交的路径数

关于两者的对应关系:

考虑前者路径,不断将其路径上与$y=0,-1,...,2-m$的某一个交点之后新增一步到$(x+1,y-1)$,即得到一条后者的路径,并且显然选择方式恰有${tot\choose m-1}$种

考虑后者的路径,分别将其路径上与$y=-1,-2,...,1-m$的第一次交点取出,显然这些交点的上一个步都是从$(x-1,y+1)$到$(x,y)$,删去这些步,即得到前者的路径

后者的路径数是一个经典的问题,在没有"与$y=-m$不交"的条件下,方案数显然为${2n+m-1\choose n-m}$,接下来考虑减去"与$y=-m$有交"的路径数,而这也等价于从$(0,-2m)$走到$(2n+m-1,1-m)$的路径数

关于两者的对应关系:显然两者的路径都与$y=-m$有交,那么将两者路径上第一次与$y=-m$相交之前的部分以$y=-m$为对称轴翻折,即可得到另一者的路径

后者的路径数显然为${2n+m-1\choose n-m-1}$(注意少向下一步还会多向上一步),即得证

类似地,可以得到
$$
[x^{n}]C^{m}(x)=[x^{n-m}]C_{0}^{m}(x)={2n-m-1\choose n-m}-{2n-m-1\choose n-m-1}
$$
由此,回到"交换枚举顺序"后的式子,直接使用通项公式计算即可

时间复杂度同样为$o(\sigma(g)m+n\log n)$,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mod 998244353
5 #define ll long long
6 int n,m,g,ans,a[N],fac[N<<1],inv[N<<1],Inv[N<<1],p[N],vis[N],phi[N];
7 int gcd(int x,int y){
8 if (!y)return x;
9 return gcd(y,x%y);
10 }
11 int c(int n,int m){
12 if ((m<0)||(m>n))return 0;
13 return (ll)fac[n]*Inv[m]%mod*Inv[n-m]%mod;
14 }
15 int C(int n,int m){
16 return (c(2*n-m-1,n-m)-c(2*n-m-1,n-m-1)+mod)%mod;
17 }
18 int C(int n){
19 return (ll)c((n<<1),n)*inv[n+1]%mod;
20 }
21 int main(){
22 fac[0]=inv[0]=inv[1]=Inv[0]=1;
23 for(int i=1;i<(N<<1);i++)fac[i]=(ll)fac[i-1]*i%mod;
24 for(int i=2;i<(N<<1);i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
25 for(int i=1;i<(N<<1);i++)Inv[i]=(ll)Inv[i-1]*inv[i]%mod;
26 phi[1]=1;
27 for(int i=2;i<N;i++){
28 if (!vis[i]){
29 p[++p[0]]=i;
30 phi[i]=i-1;
31 }
32 for(int j=1;(j<=p[0])&&(i*p[j]<N);j++){
33 vis[i*p[j]]=1;
34 if (i%p[j])phi[i*p[j]]=phi[i]*phi[p[j]];
35 else{
36 phi[i*p[j]]=phi[i]*p[j];
37 break;
38 }
39 }
40 }
41 scanf("%d%d",&n,&m);
42 g=n,ans=mod-(ll)C(n-1)*fac[n]%mod;
43 for(int i=1;i<=m;i++){
44 scanf("%d",&a[i]);
45 g=gcd(g,a[i]);
46 ans=(ll)ans*Inv[a[i]]%mod;
47 }
48 for(int i=1;i<=g;i++)
49 if (g%i==0){
50 int s=0;
51 for(int j=1;j<=n/i;j++)s=(s+(ll)C(n/i,j)*inv[j])%mod;
52 s=(ll)s*fac[n/i]%mod;
53 for(int j=1;j<=m;j++)s=(ll)s*Inv[a[j]/i]%mod;
54 ans=(ans+(ll)s*phi[i]%mod*inv[i])%mod;
55 }
56 printf("%d",ans);
57 }

[luogu5564]Say Goodbye的更多相关文章

  1. Codeforces Goodbye 2018

    Goodbye 2018 可能是我太菜考试的时候出不了$E$ 可能是我太菜考试的时候调不出$F$ 所以转化为手速场之后手速还上不去.jpg A 模拟题意... #include <cstdio& ...

  2. [T-ARA][Goodbye, OK]

    歌词来源:http://music.163.com/#/song?id=22704437 作曲 : 안영민 , 이유진 [作曲 : a-nyeong-min , i-yu-jin] 作词 : 안영민 ...

  3. UVA 11534 - Say Goodbye to Tic-Tac-Toe(博弈sg函数)

    UVA 11534 - Say Goodbye to Tic-Tac-Toe 题目链接 题意:给定一个序列,轮流放XO,要求不能有连续的XX或OO.最后一个放的人赢.问谁赢 思路:sg函数.每一段.. ...

  4. Saying Good-bye to Cambridge Again

    Saying Good-bye to Cambridge Again Very quietly I take my leave,      As quietly as I came here;     ...

  5. [新概念英语] Lesson 12 : GOODBYE AND GOOD LUCK

    Lesson 12 : GOODBYE AND GOOD LUCK New words and expressions : luck (n) 运气 例句 You're not having much ...

  6. The Last Goodbye 电影《霍比特人3:五军之战》插曲

    https://music.163.com/#/song?id=29755223 I saw the light fade from the sky我看到天空褪去色彩On the wind I hea ...

  7. 跨域跨域跨域,从此say goodbye

    跨域这个问题每个开发者都会遇到,只是时间先后而已,你不搞清楚它他就像狗皮膏药一样粘着你,在你求职生涯中不停的遇到,然后你每次都要做这个功课,终于有一天这个名词已经让我忍无可忍了,下定决心必须搞定它,要 ...

  8. UOJ Contest #50: Goodbye Jihai

    比赛传送门:Goodbye Jihai. \(\Huge{\mathbf{再见,己亥.\\你好,庚子!\\祝大家新春快乐!}}\) A. 新年的促销 这题如果直接做的话可能方向会想歪,方向对了其实就是 ...

  9. maven install报The forked VM terminated without saying properly goodbye. VM crash or System.exit called

    idea新导入的工程maven install打包报错误:The forked VM terminated without saying properly goodbye. VM crash or S ...

随机推荐

  1. C语言日记① 初识C

    概念 c语言是一种计算机语言 也就是人与计算机打交道的语言 在早期,因为计算机使用的二进制 所以早期写代码都是科学家来写的使用对应的功能二进制代码 需要用到手册,所以开发不方便 在后来,人们发明了汇编 ...

  2. mysql order by语句流程是怎么样的

    order by流程是怎么样的 注意点: select id, name,age,city from t1 where city='杭州' order by age limit 1000; order ...

  3. Flask 易错点

    1.With上下文管理器 常用: with open("file_name","wb") as f: f.write("hello flask&quo ...

  4. 力扣 - 剑指 Offer 39. 数组中出现次数超过一半的数字

    题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...

  5. 原生js-返回顶部

    html部分: <body style="height:2000px"> <div id="div1"> 返回顶部 </div&g ...

  6. SpringMVC、Spring、MyBatis整合(IDEA版)

    1 环境准备 1.1 软件架构 JDK 1.8 Spring 4.x Mybatis 3.x Maven 3.x MySQL 5.7 1.2 创建数据库 创建数据库,数据库名ssm-demo,字符集u ...

  7. 服务器端的GPU使用

    服务器端的GPU使用 查看GPU信息 查看nvidia GPU信息: # 输入指令 lspci | grep -i nvidia # 结果如下: # 04:00.0 3D controller: NV ...

  8. OO第四单元UML作业总结暨OO课程总结

    目录 目录一.第四单元UML两次作业架构设计第一次作业第二次作业二.架构设计总结与OO方法理解演进三.测试理解与实践演进四.课程收获总结五.课程改进建议六.尾声 一.第四单元UML两次作业架构设计 第 ...

  9. linux tr

    转载:tr命令_Linux tr 命令用法详解:将字符进行替换压缩和删除 (linuxde.net) tr命令 文件过滤分割与合并 tr命令可以对来自标准输入的字符进行替换.压缩和删除.它可以将一组字 ...

  10. 数据流中的中位数 牛客网 剑指Offer

    数据流中的中位数 牛客网 剑指Offer 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就 ...