[UOJ424]count
虽然题目不难,但是这应该是我第一次在考场上成功拿到计数题的不算低的分数,值得记录
如果对序列处理出$i$后面第一个比它大的位置$r_i$,那么两个序列同构的条件就是$r_i$都相同,而$r_i$构成一棵树,考虑计数树的数量
更进一步,我们只需计数那些由$1\cdots n$的排列生成的深度$\leq m$的树,因为用$[1,m]$中的数不能生成深度$\gt m$的树,生成这样的树的排列也可以通过恰当安排变成数字范围为$[1,m]$的序列
于是可以DP,设$f_{i,j}$表示深度$\leq i$,节点数为$j$的树的数量,枚举$j$在排列中的位置,有$f_{i,0}=1,f_{i,j}=\sum\limits_{k=0}^{j-1}f_{i-1,k}f_{i,j-1-k}$
设$f_{i,0\cdots n}$的生成函数为$F_i$,有$F_0=1,F_i=\frac1{1-xF_{i-1}}$
考场上就做到这里,$O(n^2\log n)$可以拿$70$分
$F_i$可以表示为$\frac{a_i}{b_i}$的形式,其中$a_i,b_i$都是$i$次多项式,推一下就可以矩阵快速幂
直接做显然不行,但因为是线性变换所以先DFT,对点值矩阵快速幂后IDFT回去即可
总时间复杂度$O(n\log n)$
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=998244353;
int mul(int a,int b){return(ll)a*b%mod;}
int ad(int a,int b){return(a+=b)>=mod?a-mod:a;}
int de(int a,int b){return(a-=b)<0?a+mod:a;}
int pow(int a,int b){
int s=1;
while(b){
if(b&1)s=mul(s,a);
a=mul(a,a);
b>>=1;
}
return s;
}
int rev[262144],N,iN;
void pre(int n){
int i,k=0;
for(N=1,k=0;N<n;N<<=1)k++;
for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
iN=pow(N,mod-2);
}
void ntt(int*a,int on){
int i,j,k,t,w,wn;
for(i=0;i<N;i++){
if(i<rev[i])swap(a[i],a[rev[i]]);
}
for(i=2;i<=N;i<<=1){
wn=pow(3,on==1?(mod-1)/i:mod-1-(mod-1)/i);
for(j=0;j<N;j+=i){
w=1;
for(k=0;k<i>>1;k++){
t=mul(a[i/2+j+k],w);
a[i/2+j+k]=de(a[j+k],t);
a[j+k]=ad(a[j+k],t);
w=mul(w,wn);
}
}
}
if(on==-1){
for(i=0;i<N;i++)a[i]=mul(a[i],iN);
}
}
int t1[262144];
void getinv(int*a,int*b,int n){
if(n==1){
b[0]=1;
return;
}
getinv(a,b,n>>1);
pre(n<<1);
memset(t1,0,N<<2);
memcpy(t1,a,n<<2);
ntt(t1,1);
ntt(b,1);
for(int i=0;i<N;i++)b[i]=mul(b[i],de(2,mul(t1[i],b[i])));
ntt(b,-1);
memset(b+n,0,(N-n)<<2);
}
struct mat{
int a[2][2];
int*operator[](int k){return a[k];}
}t;
mat operator*(mat a,mat b){
mat c;
int i,j,k;
ll t;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
t=0;
for(k=0;k<2;k++)t+=(ll)a[i][k]*b[k][j];
c[i][j]=t%mod;
}
}
return c;
}
mat pow(mat a,int b){
mat s;
s[0][0]=s[1][1]=1;
s[0][1]=s[1][0]=0;
while(b){
if(b&1)s=s*a;
a=a*a;
b>>=1;
}
return s;
}
int a[262144],b[262144],c[262144];
int main(){
int n,m,i,k,wn,w;
scanf("%d%d",&n,&m);
if(m>n){
printf("0");
return 0;
}
for(k=1;k<=n;k<<=1);
pre(k*2);
wn=pow(3,(mod-1)/N);
w=1;
for(i=0;i<N;i++){
t[0][0]=0;
t[0][1]=mod-w;
t[1][0]=t[1][1]=1;
t=pow(t,m);
a[i]=ad(t[0][0],t[1][0]);
b[i]=ad(t[0][1],t[1][1]);
w=mul(w,wn);
}
ntt(b,-1);
getinv(b,c,k);
ntt(c,1);
for(i=0;i<N;i++)a[i]=mul(a[i],c[i]);
ntt(a,-1);
printf("%d",a[n]);
}
[UOJ424]count的更多相关文章
- [2018集训队作业][UOJ424] count [笛卡尔树+括号序列+折线法+组合数学]
题面 请务必不要吐槽我的标签 传送门 思路 一个很重要的结论:原序列的一组同构的解等价于同一棵拥有$n$个节点的笛卡尔树 注意笛卡尔树的定义:父亲节点是区间最值,并且分割区间为左右部分 所以如果两个序 ...
- UOJ424 Count 生成函数、多项式求逆、矩阵快速幂
传送门 两个序列相同当且仅当它们的笛卡尔树相同,于是变成笛卡尔树计数. 然后注意到每一个点的权值一定会比其左儿子的权值大,所以笛卡尔树上还不能够存在一条从根到某个节点的路径满足向左走的次数\(> ...
- nodejs api 中文文档
文档首页 英文版文档 本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可. Node.js v0.10.18 手册 & 文档 索引 | 在单一页面中浏览 | JSON格 ...
- C#中Length和Count的区别(个人观点)
这篇文章将会很短...短到比你的JJ还短,当然开玩笑了.网上有说过Length和count的区别,都是很含糊的,我没有发现有 文章说得比较透彻的,所以,虽然这篇文章很短,我还是希望能留在首页,听听大家 ...
- [PHP源码阅读]count函数
在PHP编程中,在遍历数组的时候经常需要先计算数组的长度作为循环结束的判断条件,而在PHP里面对数组的操作是很频繁的,因此count也算是一个常用函数,下面研究一下count函数的具体实现. 我在gi ...
- EntityFramework.Extended 实现 update count+=1
在使用 EF 的时候,EntityFramework.Extended 的作用:使IQueryable<T>转换为update table set ...,这样使我们在修改实体对象的时候, ...
- 学习笔记 MYSQL报错注入(count()、rand()、group by)
首先看下常见的攻击载荷,如下: select count(*),(floor(rand(0)*2))x from table group by x; 然后对于攻击载荷进行解释, floor(rand( ...
- count(*) 与count (字段名)的区别
count(*) 查出来的是:结果集的总条数 count(字段名) 查出来的是: 结果集中'字段名'不为空的记录的总条数
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
随机推荐
- 触发器Demo
--mysql 触发器简单实例 --创建表1 )) ; --创建表2 )); --创建触发器,表一增加数据时,表二自动增加数据 create trigger t_afterinsert_on_tab1 ...
- 【API】Mysql UDF BackDoor
1.MySQL UDF是什么 UDF是Mysql提供给用户实现自己功能的一个接口,为了使UDF机制起作用,函数必须用C或C ++编写,并且操作系统必须支持动态加载.这篇文章主要介绍UDF开发和利用的方 ...
- MIUI7,Android版本5.0.2,一个程序发送自定义广播,另一个程序没有接收到
对照<第一行代码——Android>进行学习,第五章中说到广播包的相关知识,前面获取广播等程序例程都可以跑的通,但是在5.3.2节中,程序A发送自定义广播,并接收自定义广播,同时程序B也接 ...
- git fetch 命令
git fetch命令用于从另一个存储库下载对象和引用. 使用语法 git fetch [<options>] [<repository> [<refspec>…] ...
- Git log diff config高级进阶
Git 历史相关和 git config 高级进阶 前一段时间分享了一篇<更好的 git log>简要介绍怎么美化 git log 命令,其中提到了 alias命令,今天再继续谈谈 git ...
- html 列表标签
1.有序列表 <ol> <li>你好</li> <li>你好</li> <li>你好</li> </ol> ...
- pycharm tornado 项目 配置
ycharm 配置tornado项目 使得能够像django项目一样运行
- (五)HttpClient 连接超时及读取超时
第一节: HttpClient 连接超时及读取超时 HttpClient连接超时及读取超时 httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间: HttpClient连接 ...
- 开源的python机器学习模块
1. Scikit-learn Scikit-learn 是基于Scipy为机器学习建造的的一个Python模块,他的特色就是多样化的分类,回归和聚类的算法包括支持向量机,逻辑回归,朴素贝叶斯分类器, ...
- Jquery Datatable自动生成序号
公司项目里,使用的是jquerydatatable框架来展示数据的,在使用的时候遇到一个问题,就是要自动生成序号,且在分页的时候,下一页的序号紧跟着前一页的序号,下面是代码: "fnDraw ...