[2018集训队作业][UOJ450] 复读机 [DP+泰勒展开+单位根反演]
题面
思路
本文中所有$m$是原题目中的$k$
首先,这个一看就是$d=1,2,3$数据分治
d=1
不说了,很简单,$m^n$
d=2
先上个$dp$试试
设$dp[i][j]$表示前$i$个复读机用掉了$j$个机会,注意这个东西最后求出来的是分配方案,还要乘以一个$n!$
$dp[i][j]=\sum_{k=0}^j [d|k]\binom{n-j+k}{k}dp[i-1][j-k]$
$dp[i][j]=\sum_{k=0}^j [d|k]\frac{(n-j+k)!}{(n-j)!k!}dp[i-1][j-k]$
$(n-j)!dp[i][j]=\sum_{k=0}^j [d|k]\frac{1}{k!}(n-j+k)!dp[i-1][j-k]$
我们令生成函数$A(x)=\sum_{i=0}{\infty}[d|i]\frac{xi}{i!}$,$B_i(x)=\sum{j=0}^{\infty}(n-j)!dp[i][j]$
那么可以发现$B_{i+1}(x)=B_i(x)\ast A(x)$
也就是答案等于$A^m(x)$的第$n$项系数
我们看这个$A(x)$的形式,发现它下面有一堆阶乘,不由得让我们联想到泰勒展开
(我也不知道这个是怎么联想的不过就这样吧我会再写一篇博客解释的23333)
我们发现$ex=\sum_{i=0}{\infty}\frac{xi}{i!}$,同时$e{-x}=\sum_{i=0}^{\infty} (-1)^i \frac{x^i}{i!}$
那么易得$A(x)=\frac{ex+e{-x}}{2}$
所以$Am(x)=(\frac{ex+e{-x}}{2})m=\frac{1}{2m}\sum_{i=0}m \binom{m}{i}e{(2i-m)x}$
然后我们考虑$n$次项系数,发现最外面应该最后乘上去的$n!$和里面的$\frac{1}{n!}$抵消了,上面$e$的幂剩下的系数是$2i-m$
这样我们可以得到答案的表达式$ANS=\sum_{i=0}^m \binom{m}{i} (2i-m)$
d=3
emmm
我们亲爱的$e$好像用不了了
但是我们这个时候有一个神秘的东西:单位根反演!
单位根反演的公式是:$[d|i]=\frac{1}{d}\sum_{j=0}{d-1}\omega_d{ij}$
其中的$\omega_d^j$表示$d$阶单位根的$j$次方
我们代入上面的公式里面得到:
$A(x)=\sum_{i=0}{\infty}\sum_{j=0}{d-1}\frac{1}{d}\omega_d{ij}\frac{xi}{i!}$
$A(x)=\frac{1}{d}\sum_{i=0}{d-1}e{\omega_dix}$
其实可以看到上面的$d=2$就是这个式子的特殊情况
那么$d=3$怎么搞呢?
我们可以发现模数$19491001$是一个3的倍数+1的形式,那么必然存在一个三阶单位负数根根$g$(考虑费马小定理即可)
我们把这个原根求出来,然后两次暴力展开二项式定理,最后可以得到:
$Am(x)=\frac{1}{3m}\sum_{i=0}^m \sum_{j=0}^{m-i} \binom{m}{i}\binom{m-i}{j}e{(i+gj+g2(m-i-j))x}$
然后就$O(m^2\log m)$做完了
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#define MOD 19491001
#define ll long long
using namespace std;
inline ll read(){
ll re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
inline void add(ll &a,ll b){
a+=b;
if(a>=MOD) a-=MOD;
}
inline ll qpow(ll a,ll b){
ll re=1;
while(b){
if(b&1) re=re*a%MOD;
a=a*a%MOD;b>>=1;
}
return re;
}
ll n,m,d,f[1000010],finv[1000010],inv[1000010],g=7,inv3,w1,w2;
void init(){
ll i,len=1000000;
f[0]=f[1]=finv[0]=finv[1]=inv[1]=1;
for(i=2;i<=len;i++) f[i]=f[i-1]*i%MOD;
finv[len]=qpow(f[len],MOD-2);
for(i=len;i>2;i--) finv[i-1]=finv[i]*i%MOD;
for(i=2;i<=len;i++) inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD;
}
inline ll C(ll x,ll y){
return f[x]*finv[y]%MOD*finv[x-y]%MOD;
}
int main(){
n=read();m=read();d=read();
ll i,j;ll ans=0,tmp;init();
inv3=qpow(3,MOD-2);
w1=qpow(g,(MOD-1)/3);
w2=w1*w1%MOD;
if(d==1) cout<<qpow(m,n)<<'\n';
if(d==2){
for(i=0;i<=m;i++){
add(ans,C(m,i)*qpow((2*i-m+MOD)%MOD,n)%MOD);
}
cout<<ans*qpow(qpow(2,m),MOD-2)%MOD<<'\n';
}
if(d==3){
for(i=0;i<=m;i++){
for(j=0;j<=m-i;j++){
tmp=(i+w1*j+w2*(m-i-j))%MOD;
add(ans,C(m,i)*C(m-i,j)%MOD*qpow(tmp,n)%MOD);
}
}
cout<<ans*qpow(qpow(3,m),MOD-2)%MOD<<'\n';
}
}
[2018集训队作业][UOJ450] 复读机 [DP+泰勒展开+单位根反演]的更多相关文章
- uoj450 【集训队作业2018】复读机(生成函数,单位根反演)
uoj450 [集训队作业2018]复读机(生成函数,单位根反演) uoj 题解时间 首先直接搞出单个复读机的生成函数 $ \sum\limits_{ i = 0 }^{ k } [ d | i ] ...
- 处女座与复读机 DP
题目链接:https://ac.nowcoder.com/acm/contest/327/G 题意:给你两个字符串序列,让你根据第二个序列判断是不是 复读机,复读机会有以下特征 1. 将任 ...
- 【做题】UOJ450 - 复读机——单位根反演
原文链接 https://www.cnblogs.com/cly-none/p/UOJ450.html 题意:请自行阅读. 考虑用生成函数来表示答案.因为秒之间是有序的,所以这应当是个指数生成函数.故 ...
- UOJ450 复读机
题意:n个位置,k种颜色.求有多少种方案使得每种颜色恰出现d的倍数次. 解:d=1就快速幂,n,k很小就DP,记得乘组合数来分配位置. d = 2 / 3的时候,考虑生成函数. f(x) = ∑[d ...
- [2018集训队作业][UOJ424] count [笛卡尔树+括号序列+折线法+组合数学]
题面 请务必不要吐槽我的标签 传送门 思路 一个很重要的结论:原序列的一组同构的解等价于同一棵拥有$n$个节点的笛卡尔树 注意笛卡尔树的定义:父亲节点是区间最值,并且分割区间为左右部分 所以如果两个序 ...
- 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)
[UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...
- UOJ#450. 【集训队作业2018】复读机 排列组合 生成函数 单位根反演
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ450.html 题解 首先有一个东西叫做“单位根反演”,它在 FFT 的时候用到过: $$\frac 1 ...
- UOJ #450. 【集训队作业2018】复读机
前置知识单位根反演自己去浅谈单位根反演看(此外可能需要一定的生成函数的姿势) 首先一看\(d\)这么小,那我们来分类讨论一下吧 当\(d=1\)时,显然答案就是\(k^n\) 当\(d=2\)时,如果 ...
- 【UOJ#450】[集训队作业2018] 复读机
题目链接 题目描述 群里有\(k\)个不同的复读机.为了庆祝平安夜的到来,在接下来的\(n\)秒内,它们每秒钟都会选出一位优秀的复读机进行复读.非常滑稽的是,一个复读机只有总共复读了\(d\)的倍数次 ...
随机推荐
- Jsp刷新分页模板,很全
1.用来实现上一页下一页,我直接写到查询页面上 <%--page的分页--%> <style type="text/css"> a { color: # ...
- JS代码优化及技巧
案例一 对象参数独立化 情景:为多个日期文本框添加日期选择器 源代码: $('#PropertySalesAdviceExchnagedDate1').datepicker({ showOn: 'b ...
- C#中Mutex的用法
C#中Mutex是互斥锁,位于System.Threading 命名空间中. 顾名思义,它是一个互斥的对象,同一时间只有一个线程可以拥有它,该类还可用于进程间同步的同步基元. 如果当前有一个线程拥有它 ...
- unity面试题一
一:什么是协同程序? 在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足. 二:Unity3d中 ...
- WeTest功能优化第3期:业内首创,有声音的云真机
第3期功能优化目录 [云真机远程调试]音频同步传输实现测试有声 [兼容性测试报告]新增视频助力动态定位问题 [云真机远程调试]菜单栏优化助力机型选择 本期介绍的新功能,秉承创造用户需求的理念,在云真机 ...
- 实现Bidirectional LSTM Classifier----深度学习RNN
双向循环神经网络(Bidirectional Recurrent Neural Networks,Bi-RNN),Schuster.Paliwal,1997年首次提出,和LSTM同年.Bi-RNN,增 ...
- C#通过gridview导出excel
[CustomAuthorize] public FileResult ExportQuestionCenterExcel(SearchBaseQuestion search) ...
- 6.hdfs的存储过程
1.hdfs 怎么存储 切割存储 2. 为何每块是128m 与io读写速度有关,一般人的接受速度1s中,而磁盘的读写速度为100m/s,在读取文件时候需要硬盘寻找地址,一般读懂速度和寻找之间的比例是1 ...
- 4.安装hive
下载安装包并解压安装元数据库配置hive添加hvie环境变量修改hive-env.sh修改hive配置文件初始化metastore使用hive cli配置hivemestore配置hiveserv ...
- 最多水容器(M)
题目 给定n个非负整数a 1,a 2,...,a n,其中每个代表坐标(i,a i)处的一个点.绘制n条垂直线,使得线i的两个端点处于(i,a i)和(i,0)处.找到两条线,它们与x轴一起形成一个容 ...