[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 ...
随机推荐
- bootstrap_bootstrap中日历范围选择插件daterangepicker的使用
1.引入脚本 <link rel="stylesheet" type="text/css" href="assets/css/bootstrap ...
- 单调栈(G - Sliding Window POJ - 2823 )
题目链接:https://cn.vjudge.net/contest/276251#problem/G 题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值 ...
- 小白欢乐多——记ssctf的几道题目
小白欢乐多--记ssctf的几道题目 二哥说过来自乌云,回归乌云.Web400来源于此,应当回归于此,有不足的地方欢迎指出. 0x00 Web200 先不急着提web400,让我们先来看看web200 ...
- 禅道CMS 获文件名脚本
use Net::HTTP::GET; use Base64; ; windowWidth=; windowHeight=; sid=jg9g2mk5kmru46lmd3g2evoc87>; # ...
- 超简单的qps统计方法(推荐)【转】
统计最近N秒内的QPS值(包括每秒select,insert等值) mysql> select variable_name,sum(per_sec) as qps from (select st ...
- SQL 根据关联表更新主表中字段数据
今天遇到一个客户的数据更新问题,两个相关联的表,一个主表用于保存单据主要信息,一个副表用于保存单据的明细信息:现在要把主表的其中一个字段的数据更新到副表的一个字段中保存.精通的SQL语法的,当然是很简 ...
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...
- Kaggle案例分析1--Bestbuy
1. 引言 Kaggle是一个进行数据挖掘和数据分析在线竞赛网站, 成立于2010年. 与Kaggle合作的公司可以提供一个数据+一个问题, 再加上适当的奖励, Kaggle上的计算机科学家和数据科学 ...
- Vue 实现countDown倒计时
项目中要用到倒计时,用Vue 实现了一个 <template> <transition name="bkcd"> <div class="b ...
- Tomcat底层实现
package myserver; import java.io.IOException;import java.net.ServerSocket;import java.net.Socket; pu ...