前置知识单位根反演自己去浅谈单位根反演看(此外可能需要一定的生成函数的姿势)

首先一看\(d\)这么小,那我们来分类讨论一下吧

当\(d=1\)时,显然答案就是\(k^n\)

当\(d=2\)时,如果你知道可重排列的指数型生成函数:

\[G(x)=\sum_{i=0} \frac{x^{2i}}{(2i)!}
\]

那么就跳过以下部分直接去看转化,我们来推导一下这个生成函数

直接搞一个DP,设\(f_{i,j}\)表示前\(i\)个复读机选了\(j\)个时间的方案数,转移的时候枚举这个复读机复读了几次

\[f_{i,j}=\sum_{k=0}^j [2|k] C_{n-(j-k)}^k f_{i-1,j-k}
\]

把\(f_i\)看做一个指数型生成函数,那么每次加入一个复读机相当于乘上了一个上面的\(\sum_{i=0} [2|i] \frac{x^i}{i!}\)

由于我们这里的生成函数没有考虑每次操作间的顺序,因此乘上\(n!\)有:

\[Ans=n!\cdot G(x)^k[x^n]
\]

然后这个\(G(x)\)细看有点熟悉,稍加推导会发现它就是\(\frac{e^x+e^{-x}}{2}\),那么这里还是直接用二项式定理展开

\[Ans=n!\cdot (\frac{(e^x+e^{-x})^k}{2^k})=n!\cdot(\frac{\sum_{i=0}^k C_k^i \cdot e^{{2i-k}x}}{2^k})
\]

然后我们求\([x^n]\),泰勒逆展开之后会发现分母里的\(n!\)和前面的\(n!\)抵消了,因此

\[Ans=\frac{\sum_{i=0}^k C_k^i\cdot (2i-k)^n}{2^k}
\]

直接\(O(k)\)计算即可

当\(d=3\)时,和上面类似我们可以直接得出此时的\(G(x)=\sum_{i=0} [3|i] \frac{x^i}{i!}\),然后来一发单位根反演:

\[G(x)=\sum_{i=0}\frac{1}{3}\sum_{j=0}^2 \frac{\omega_3^{ij}\cdot x^i}{i!}
\]

\[=\frac{1}{3}\sum_{j=0}^2 \sum_{i=0}\frac{(\omega_3^j\cdot x)^i}{i!}
\]

快乐地泰勒逆展开一下就有:

\[G(x)=\frac{1}{3}\sum_{j=0}^2 e^{\omega_3^jx}
\]

然后还是那个式子:

\[Ans=n!\cdot G(x)^k[x^n]
\]

\[=n!\cdot (\frac{\sum_{a+b+c=k} (e^{(a\omega_3^0+b\omega_3^1+c\omega_3^2)x})\cdot \frac{k!}{a!b!c!}}{3^k})
\]

还是泰勒逆展开,最后就有:

\[Ans=\frac{\sum_{a+b+c=k} (a\omega_3^0+b\omega_3^1+c\omega_3^2)\cdot \frac{k!}{a!b!c!}}{3^k}
\]

然后我们会发现\(d=2\)的情况其实也可以这么做,不过由于此时后面那个系数就是组合数,而且此时单位根就是\(\pm 1\),因此也可以推回上面的式子

最后说句闲话,这道题用\(d=3\)时的方法推一推就可以得到一个广泛的做法,此时的复杂度是\(O(k^{d-1})\)

打了好多公式累死了233

#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=500005,mod=19491001;
int n,k,d,fact[N],inv[N],ans,cnt,pri[100],w0,w1,w2;
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void inc(int &x,CI y)
{
if ((x+=y)>=mod) x-=mod;
} inline void init(CI n)
{
RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
}
inline int C(CI n,CI m)
{
return 1LL*fact[n]*inv[m]%mod*inv[n-m]%mod;
}
inline int getroot(CI p)
{
RI i,j; int x=p-1; for (i=2;i*i<=x;++i) if (x%i==0)
for (pri[++cnt]=i;x%i==0;x/=i); for (i=2;;++i)
{
bool flag=1; for (j=1;j<=cnt;++j)
if (quick_pow(i,(p-1)/pri[j])==1) { flag=0; break; }
if (flag) return quick_pow(i,(mod-1)/3);
}
}
int main()
{
RI i,j; scanf("%d%d%d",&n,&k,&d); switch (d)
{
case 1:
printf("%d",quick_pow(k,n)); break;
case 2:
for (init(k),i=0;i<=k;++i) inc(ans,1LL*C(k,i)*quick_pow(2*i-k,n)%mod);
printf("%d",1LL*ans*quick_pow(2,mod-1-k)%mod); break;
case 3:
w0=1; w1=getroot(mod); w2=1LL*w1*w1%mod; init(k);
for (i=0;i<=k;++i) for (j=0;i+j<=k;++j)
inc(ans,1LL*quick_pow((1LL*w0*i%mod+1LL*w1*j%mod+1LL*w2*(k-i-j)%mod)%mod,n)*
fact[k]%mod*inv[i]%mod*inv[j]%mod*inv[k-i-j]%mod);
printf("%d",1LL*ans*quick_pow(3,mod-1-k)%mod); break;
}
return 0;
}

UOJ #450. 【集训队作业2018】复读机的更多相关文章

  1. uoj #450[集训队作业2018]复读机

    传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...

  2. 【UOJ#450】[集训队作业2018] 复读机

    题目链接 题目描述 群里有\(k\)个不同的复读机.为了庆祝平安夜的到来,在接下来的\(n\)秒内,它们每秒钟都会选出一位优秀的复读机进行复读.非常滑稽的是,一个复读机只有总共复读了\(d\)的倍数次 ...

  3. [2018集训队作业][UOJ450] 复读机 [DP+泰勒展开+单位根反演]

    题面 传送门 思路 本文中所有$m$是原题目中的$k$ 首先,这个一看就是$d=1,2,3$数据分治 d=1 不说了,很简单,$m^n$ d=2 先上个$dp$试试 设$dp[i][j]$表示前$i$ ...

  4. UOJ 422 [集训队作业2018] 小Z的礼物 min-max容斥 期望 轮廓线dp

    LINK:小Z的礼物 太精髓了 我重学了一遍min-max容斥 重写了一遍按位或才写这道题的. 还是期望多少时间可以全部集齐. 相当于求出 \(E(max(S))\)表示最后一个出现的期望时间. 根据 ...

  5. 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)

    [UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...

  6. uoj450 【集训队作业2018】复读机(生成函数,单位根反演)

    uoj450 [集训队作业2018]复读机(生成函数,单位根反演) uoj 题解时间 首先直接搞出单个复读机的生成函数 $ \sum\limits_{ i = 0 }^{ k } [ d | i ] ...

  7. UOJ #449. 【集训队作业2018】喂鸽子

    UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...

  8. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    [UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...

  9. UOJ#418. 【集训队作业2018】三角形

    #418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...

  10. UOJ#422. 【集训队作业2018】小Z的礼物

    #422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...

随机推荐

  1. js-04-函数学习

    一.什么为函数? 函数是用来执行某些特定功能的代码,为了减少代码的重复使用,将函数作为代码使用,在需要时随时调用使用. 二.函数的声明(函数名严格区分大小写) 1.function命令 functio ...

  2. Flutter 即学即用系列博客总结篇

    前言 迟到的总结篇,其实大家看我之前发的系列博客最后一篇,发文时间是 3 月 29 日.距离现在快两个月了. 主要是因为有很多事情在忙,所以这篇就耽搁了. 今天终于可以跟大家会面了. 系列博客背景 F ...

  3. Saltstack_使用指南09_远程执行-编写执行模块

    1. 主机规划 salt 版本 [root@salt100 ~]# salt --version salt (Oxygen) [root@salt100 ~]# salt-minion --versi ...

  4. rocksdb学习笔记

    rocksdb是在leveldb的基础上优化而得,解决了leveldb的一些问题. 主要的优化点 1.增加了column family,这样有利于多个不相关的数据集存储在同一个db中,因为不同colu ...

  5. 正则表达式(Regular Expression)入门

    一.正则表达式的使用场景: 上传文件类型的判断,电子邮件的判断,电话号码的判断,文本的搜索与替换. 二.正则表达式的语法规则: 1.行定位符: ^表示行的开始,$表示行的结尾 ^tm 可以匹配  tm ...

  6. React每隔0.2s颜色变淡 之settimeOut变成setInterval

    案例 每隔0.2s颜色变淡 公共数据是放在state中的哦! 代码如下 import React, { Component } from "react"; import { set ...

  7. jQuery入门和DOM对象

    jQuery入门和DOM对象 1.开发准备 1. 下载的版本: jquery-3.3.1.min.js :压缩版,发布版84.8KB jquery-3.3.1.js :常规版,开发版265KB 2. ...

  8. Python中的模块引用机制

    一.模块引用 Def: 在Python 程序中使用另一个文件定义的类(方法).函数.数据等 被引用模块位置.通常 Python2 : "/Library/Python/2.7/site-pa ...

  9. Python 变量与运算符

    变量 基本概念: 1. 变量,名字,数据的唯一标识2.变量命名: 字母.数字.下划线: 不能以数字开头: 区分大小写: 不能使用保留字和关键字: 命名要有意义:(多个单词时,推荐使用下划线连接) 3. ...

  10. linux命令-开关机命令与系统痕迹命令

    一.关机和重启命令 1.sync 命令 命令名称:sync 英文原意:flush file system buffers 所在路径:/bin/sync 执行权限:所有用户 功能描述:刷新文件系统缓冲区 ...