UOJ#424 【集训队作业2018】count
题意
我们定义长度为\(n\),每个数为\(1\sim m\)之间的整数且\(1\sim m\)都至少出现一次的序列为合法序列。再定义\(pos(l,r)\)表示这个序列的区间\([l,r]\)之间的最大值出现的位置(如果有多个取最左端),如果两个序列\(A\),\(B\)的所有\(pos\)值都相同,则\(A\)和\(B\)是同构的。问有多少不同构的合法序列。
\(n,m\leq 100000\)。
题解
首先\(n<m\)显然是无解的。
考虑什么样的序列是同构的,那么我们首先要有一个能方便的表示区间最大值的位置的数据结构,那就是笛卡尔树。显然只要两个序列的笛卡尔树同构,这两个序列就同构。
那么关于\(m\)的限制应该怎么办呢?
由于有多个相同的算在最左边,因此可以发现在笛卡尔树中,每个点的左儿子的键值都小于这个点的键值,右儿子则是小于等于。那么如果这颗笛卡尔树要是合法的,就有一个必要条件:记\(len(x)\)代表从根到节点\(x\)经过的走向左儿子的路径数量(简称为左链长度),那么对于任意的\(x\),有\(len(x)<m\)。
接下来我们证明在\(n\geq m\)时这是一个充分条件。考虑用满足条件的笛卡尔树构造一个合法序列,只需要先将最长的链中每个点赋值为\(m-点的深度\)(根的深度为\(0\)),接下来不断寻找最深的没有赋值的点,将其赋值为没有出现过的数中的最小值即可。剩下的点只需要赋值为\(父亲的值-1\)。易证这样一定可以得到一个合法序列。
于是我们只需要求\(n\)个点,左链长度不超过\(m-1\)的二叉树个数即可。
设\(f_{i,j}\)表示\(j\)个点,左链长度不超过\(i\)的二叉树个数,考虑枚举左子树的大小,于是就有:
\]
平凡情况有\(f_{0,j}=1\)。
那么将上式表达为卷积,就有:
\]
等价于:
\]
直接做似乎很不可做,但是通过这个式子我们可以得到\(f_i\)可以分解为\(\frac{a_i}{b_i}\),其中\(a_i\),\(b_i\)是两个次数界为\(O(i)\)的多项式,那么考虑求\(a_i\),\(b_i\):
\]
\]
于是就得到\(a_i=b_{i-1}\),\(b_i=b_{i-1}-a_{i-1}x\),将转移关系用矩阵来表示就得到:
\]
那么可以通过矩阵快速幂来求\(a_i\),\(b_i\)。但是直接在矩阵中用多项式进行计算会很麻烦,因此不妨考虑用单位根代入求点值,用\(\rm IDFT\)插出多项式即可。复杂度\(O(n\log n)\)。
#include<cstdio>
#include<cstring>
#include<algorithm>
using std::swap;
const int mod=998244353;
inline int add(int a,int b)
{
return (a+=b)>=mod?a-mod:a;
}
inline int sub(int a,int b)
{
return (a-=b)<0?a+mod:a;
}
inline int mul(int a,int b)
{
return (long long)a*b%mod;
}
inline int qpow(int a,int b)
{
int res=1;
for(;b;a=mul(a,a),b>>=1)
if(b&1)
res=mul(res,a);
return res;
}
const int N=1e6+5;
int rev[N];
inline void ntt(int *f,int n,int p)
{
int w,wi,u,t;
register int i,j,k;
for(i=0;i<n;i++)
if(i<(rev[i]=i&1?rev[i^1]|n>>1:rev[i>>1]>>1))
swap(f[i],f[rev[i]]);
for(i=1;wi=qpow(qpow(3,(mod-1)/(i<<1)),p^1?mod-2:1),i<<1<=n;i<<=1)
for(j=0;w=1,j<n;j+=i<<1)
for(k=0;k<i;w=mul(w,wi),k++)
u=f[j+k],t=mul(w,f[j+k+i]),f[j+k]=add(u,t),f[j+k+i]=sub(u,t);
if(!~p)
for(w=qpow(n,mod-2),i=0;i<n;i++)
f[i]=mul(w,f[i]);
return;
}
inline void poly_mul(int *f,int *g,int n)
{
register int i;
memset(f+n,0,sizeof(int)*n);
memset(g+n,0,sizeof(int)*n);
ntt(f,n<<1,1);f==g?void():ntt(g,n<<1,1);
for(i=0;i<n<<1;i++)
f[i]=mul(f[i],g[i]);
ntt(f,n<<1,-1);f==g?void():ntt(g,n<<1,-1);
return;
}
int F[N],G[N];
int _g[N];
inline void poly_inv(int *f,int n)
{
register int i,j;
memset(_g,0,sizeof(int)*n);
_g[0]=qpow(f[0],mod-2);
for(i=1;i<<1<=n;i<<=1)
{
memcpy(F,f,sizeof(int)*(i<<1));
memcpy(G,_g,sizeof(int)*i);
poly_mul(G,G,i);poly_mul(F,G,i<<1);
for(j=0;j<i<<1;j++)
_g[j]=sub(add(_g[j],_g[j]),F[j]);
}
memcpy(f,_g,sizeof(int)*n);
return;
}
int a[2][2],b[2][2],res[2][2];
inline void matrix_qpow(int p)
{
res[0][0]=res[1][1]=1;res[0][1]=res[1][0]=0;
for(;p;p>>=1)
{
if(p&1)
{
b[0][0]=add(mul(res[0][0],a[0][0]),mul(res[0][1],a[1][0]));
b[0][1]=add(mul(res[0][0],a[0][1]),mul(res[0][1],a[1][1]));
b[1][0]=add(mul(res[1][0],a[0][0]),mul(res[1][1],a[1][0]));
b[1][1]=add(mul(res[1][0],a[0][1]),mul(res[1][1],a[1][1]));
memcpy(res,b,sizeof(b));
}
b[0][0]=add(mul(a[0][0],a[0][0]),mul(a[0][1],a[1][0]));
b[0][1]=add(mul(a[0][0],a[0][1]),mul(a[0][1],a[1][1]));
b[1][0]=add(mul(a[1][0],a[0][0]),mul(a[1][1],a[1][0]));
b[1][1]=add(mul(a[1][0],a[0][1]),mul(a[1][1],a[1][1]));
memcpy(a,b,sizeof(b));
}
return;
}
int n,m;
int f[N],g[N];
signed main()
{
int _=1<<17,w=1,wi=qpow(3,(mod-1)/_);
register int i;
scanf("%d%d",&n,&m);
if(n<m)
return puts("0"),0;
for(i=0;i<_;i++)
{
a[0][0]=0;a[0][1]=1;a[1][0]=sub(0,w);a[1][1]=1;
matrix_qpow(m);
f[i]=add(res[0][0],res[0][1]);g[i]=add(res[1][0],res[1][1]);
w=mul(w,wi);
}
ntt(f,_,-1);ntt(g,_,-1);
poly_inv(g,_);
poly_mul(f,g,_);
printf("%d\n",f[n]);
return 0;
}
UOJ#424 【集训队作业2018】count的更多相关文章
- uoj #450[集训队作业2018]复读机
传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...
- UOJ 422 [集训队作业2018] 小Z的礼物 min-max容斥 期望 轮廓线dp
LINK:小Z的礼物 太精髓了 我重学了一遍min-max容斥 重写了一遍按位或才写这道题的. 还是期望多少时间可以全部集齐. 相当于求出 \(E(max(S))\)表示最后一个出现的期望时间. 根据 ...
- UOJ #449. 【集训队作业2018】喂鸽子
UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
- 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)
[UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...
- 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)
[UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...
- UOJ#418. 【集训队作业2018】三角形
#418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...
- UOJ#422. 【集训队作业2018】小Z的礼物
#422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...
- UOJ#428. 【集训队作业2018】普通的计数题
#428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...
- uoj450 【集训队作业2018】复读机(生成函数,单位根反演)
uoj450 [集训队作业2018]复读机(生成函数,单位根反演) uoj 题解时间 首先直接搞出单个复读机的生成函数 $ \sum\limits_{ i = 0 }^{ k } [ d | i ] ...
- [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥
题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...
随机推荐
- Python2.7-logging模块
logging模块,用于记录程序的运行情况,可将需要的信息打印到控制台或是日志文件中 1.Logger对象 Logger对象从来不会被直接使用,都是通过logging.getLogger(name)这 ...
- TM1629A驱动程序
网上看了很多1629驱动程序,很乱,下载了几个整合了一下,下面的程序还没有烧录到开发板里面测试,程序已经做好了,但是这个方案老板不做了,所以只能在这里放着了,留着以后用吧 void TM1629A_W ...
- 为什么给GIT库打TAG不成功
首先,右击文件夹,选择“TortoiseGit”,再选择“Create Tag...". 然后在Tag一栏中输入Tag名. 接下来点”OK“确定设置项. 最后PUSH到服务器上, ...
- uC/OS-III 时钟节拍,时间管理,时间片调度
uC/OS-III 时钟节拍,时间管理,时间片调度 时钟节拍 时钟节拍可谓是 uC/OS 操作系统的心脏,它若不跳动,整个系统都将会瘫痪. 时钟节拍就是操作系统的时基,操作系统要实现时间上的管理, ...
- 牛掰本机限速软件appband
带宽调度器AppBand可以为Windows应用程序分配网络带宽并指定数据收发的优先级,用软件的方式实现桌面应用的简单QOS调度.(1) P2P方式的下载软件(BT/eMule/迅雷等)或者在线播放占 ...
- 20155304田宜楠《网络对抗技术》Exp1 PC平台逆向破解(5)M
Exp1 PC平台逆向破解(5)M 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序 ...
- [Deep-Learning-with-Python]计算机视觉中的深度学习
包括: 理解卷积神经网络 使用数据增强缓解过拟合 使用预训练卷积网络做特征提取 微调预训练网络模型 可视化卷积网络学习结果以及分类决策过程 介绍卷积神经网络,convnets,深度学习在计算机视觉方面 ...
- 06-Git-Linux命令
Git 命令 Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 一.新建代码库 # 新建一个目录,将其初始化为Git代 ...
- 5.Xilinx RapidIO核例子工程源码分析
https://www.cnblogs.com/liujinggang/p/10091216.html 一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件:V ...
- P2371 [国家集训队]墨墨的等式
膜意义下最短路. 把最小的\(a\)抠出来,作为模数\(mod\),然后建点编号为\(0\)到\(mod-1\),对每个数\(a\)连边\((i,(a+i)\mod mod)\)点\(i\)的最短路就 ...