UOJ#428. 【集训队作业2018】普通的计数题
模型转化好题
所以变成统计有标号合法的树的个数。
合法限制:
1.根标号比子树都大
2.如果儿子全是叶子,数量B中有
3.如果存在一个儿子不是叶子,数量A中有
然后考虑DP
直接枚举根的儿子的情况
cdq分治NTT还是很恶心的
不光是自己卷自己,还是互相卷
进行一番化简和平移之后,可以转化为cdq分治NTT的形式:
怎么好做怎么来。
反正我最后推的式子有如下特点(式子就不写了):
为了方便,钦定g[0],f[0],g[1],f[1]都是0
对于f,a是固定的,a向右平移一下,然后就是cdq分治的模板题了
对于g,当cdq的分治区间l不是0的时候,要F作为[l,mid],G作为[ql,qr],和G作为[l,mid],F作为[ql,qr]做两遍
这样其实剩下g[n]=g[0]*f[n],但是g[0]=0,所以不用管
代码:
const int N=+;
int jie[N],inv[N];
int f[N],g[N];
int n,sa,sb;
int ta[N],b[N],a[N];
void divi(int l,int r,int ql,int qr){
// cout<<" divi "<<l<<" "<<r<<" ql "<<ql<<" qr "<<qr<<endl;
if(l==&&r==){
f[]=f[]=g[]=g[]=;
return;
}
if(l==r){
f[l]=ad(mul(f[l],jie[l-]),b[l-]);
g[l]=ad(f[l],mul(g[l],jie[l-]));
f[l]=mul(f[l],inv[l-]);
g[l]=mul(g[l],inv[l]);
return;
}
int mid=(l+r)>>;
int qmd=(ql+qr)>>;
divi(l,mid,ql,qmd);
Poly A,G;
A.resize(qr-ql+);
G.resize(mid-l+);
for(reg i=ql;i<=qr;++i){
A[i-ql]=a[i];
}
for(reg i=l;i<=mid;++i){
G[i-l]=g[i];
}
A*=G;
for(reg i=mid+;i<=r;++i){
f[i]=ad(f[i],A[i-l]);
} if(l==){
Poly F;G.clear();
F.resize(mid-l+);
G.resize(mid-l+);
for(reg i=l;i<=mid;++i){
F[i-l]=f[i];
G[i-l]=g[i];
}
F=F*G;
for(reg i=mid+;i<=r;++i){
g[i]=ad(g[i],F[i]);
}
}else{
Poly F;G.clear();
F.resize(qr-ql+);
G.resize(mid-l+);
for(reg i=l;i<=mid;++i){
G[i-l]=g[i];
}
for(reg i=ql;i<=qr;++i){
F[i-ql]=f[i];
}
F=F*G;
for(reg i=mid+;i<=r;++i){
g[i]=ad(g[i],F[i-l]);
}
F.clear();G.clear();
F.resize(mid-l+);
G.resize(qr-ql+);
for(reg i=ql;i<=qr;++i){
G[i-ql]=g[i];
}
for(reg i=l;i<=mid;++i){
F[i-l]=f[i];
}
F=F*G;
for(reg i=mid+;i<=r;++i){
g[i]=ad(g[i],F[i-l]);
}
}
divi(mid+,r,ql,qmd);
}
int main(){
rd(n);rd(sa);rd(sb);int x;
for(reg i=;i<=sa;++i){rd(x);ta[x]=;}
for(reg i=;i<=sb;++i){rd(x);b[x]=;}
if(n==){
puts("");return ;
}
int m;
for(m=;m<=n;m<<=);
jie[]=;
for(reg i=;i<=m;++i) jie[i]=mul(jie[i-],i);
inv[m]=qm(jie[m],mod-);
for(reg i=m-;i>=;--i) inv[i]=mul(inv[i+],i+); for(reg i=;i<=m;++i){
a[i]=mul(ta[i-],inv[i-]);
}
a[]=; divi(,m-,,m-);
ll ans=f[n];
ans=mul(ans,jie[n-]);
ot(ans);
return ;
}
树形结构很巧妙啊
f,g互相卷的分治NTT第一次写,还是举一个0,1,2,3,4,5,6,7的例子最好理解了!
UOJ#428. 【集训队作业2018】普通的计数题的更多相关文章
- 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#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 #449. 【集训队作业2018】喂鸽子
UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
- 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会变,中途 ...
- [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP
题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ...
- uoj450 【集训队作业2018】复读机(生成函数,单位根反演)
uoj450 [集训队作业2018]复读机(生成函数,单位根反演) uoj 题解时间 首先直接搞出单个复读机的生成函数 $ \sum\limits_{ i = 0 }^{ k } [ d | i ] ...
随机推荐
- mysql on windows的安装
1.去官网下载合适的压缩包 网址:https://dev.mysql.com/downloads/file/?id=476233 (拉到最下面点击 No thanks,just start my do ...
- [JZOJ5232] 【NOIP2017模拟A组模拟8.5】带权排序
题目 题目大意 有一个数列AAA,数列上的每个数都是在[li,ri][l_i,r_i][li,ri]范围内随机的数. 将这个数列进行稳定排序,得到每个位置在排序后的排名pip_ipi. f(A) ...
- js 数据绑定
// 回流:(重排 reflow) 当HTML的DOM结构(删除.增加.位置等)发生改变时引起DOM回流.浏览器重新计算DOM结构,重新的对当前DOM结构进行渲染 // 重绘:某一个元素的部分 ...
- codeforces 1131D-Gourmet choice
传送门:QAQQAQ 题意:有两个数组,一个数组有n个数,另一个数组有m个数.s[i][j]表示第一个数组第i个数和第二个数组第j个数的大小关系,要求构造出一种方案,使条件成立. 先考虑没有等于号的情 ...
- day 42 01--CSS的引入方式及CSS选择器
01--CSS的引入方式及CSS选择器 本节目录 一 CSS介绍 二 行内样式 三 内接样式 四 外接样式 五 CSS的选择器 六 CSS的高级选择器 七 CSS的属性选择器 八 CSS的伪类选择 ...
- 黑裙晖安装后修改mac和sn
d当前使用6.2 打开putty sudo -i 然后在/tmp目录下创建一个临时目录,名字随意,如:boot mkdir -p /tmp/boot 第四步:切换到dev目录 cd /dev 第五步: ...
- 学而有道--思维导图式总结(一):Nosql分类
前言: 众所周知,学习是需要方法的.作为一名java程序员,我们需要学习无数的技能,然而我们的大脑并不买账,学习了一项知识,时间一久就会遗忘, 如何更好高效的回忆起曾经学习过的知识,是极其重要的. 有 ...
- 在scrapy中将数据保存到mongodb中
利用item pipeline可以实现将数据存入数据库的操作,可以创建一个关于数据库的item pipeline 需要在类属性中定义两个常量 DB_URL:数据库的URL地址 DB_NAME:数据库的 ...
- 5行代码怎么实现Hadoop的WordCount?
初学编程的人,都知道hello world的含义,当你第一次从控制台里打印出了hello world,就意味着,你已经开始步入了编程的大千世界,这和第一个吃螃蟹的人的意义有点类似,虽然这样比喻并不恰当 ...
- OSG在VS2008下的配置安装
一.准备工作 下载相关的工具软件: 1, 最新版的OSG库:OpenSceneGraph-2.8.2.zip. 2, 安装源代码所需要的工具:cmake-2.6.4-win32-x86.zip 3, ...