题解[LuoguP5591]小猪佩奇学数学

前置知识

  1. 基本数论推式子能力,如分配律结合律
  2. 等比数列求和 \(\sum_{i=a}^bx^i=\dfrac{x^{b+1}-x^a}{x-1}\)
  3. 二项式定理 \((a+b)^k=\sum_{i=0}^k\dbinom ki a^ib^{k-i}\) 及其特殊形式 \((a+1)^k=\sum_{i=1}^k\dbinom ki a^i\)
  4. 组合恒等式 \(m\dbinom nm=n\dbinom {n-1}{m-1}\)
  5. 单位根反演 \([d\mid n]=\dfrac 1d\sum_{i=0}^{d-1} \omega_d^{ni}\)

题意简述

\[\begin{aligned}
\sum_{i=0}^n\binom ni p^i \left\lfloor\frac ik\right\rfloor
\end{aligned}
\]

其中 \(n,p,k\) 给定,对 \(998244353\) 取模。

解题过程

可以发现如果去掉最后的 \(\left\lfloor\dfrac ik \right \rfloor\),那么二项式定理逆用即可,所以我们考虑保留前半部分不动。

要处理 \(\left\lfloor\dfrac ik \right\rfloor\) 类问题,一般依靠其下取整取值数量来做题,但可以发现 \(f(i)=\dbinom ni p^i\) 不方便前缀和,难以使用这个套路。

所以我们考虑转换,将其改写为 \(g(x)=\sum_{i=0}^x[k|i]-1\),这里为了方便我们将 \(0\) 也算入其中。

那么就可以再使用单位根反演了。

\[\begin{aligned}
ans&=\sum_{i=0}^n\binom ni p^i \left\lfloor\frac ik\right\rfloor\\
&=\sum_{i=0}^n\binom ni p^i \sum_{j=0}^i [k|j]-\sum_{i=0}^n\binom ni p^i\\
&=\sum_{i=0}^n\binom ni p^i \sum_{j=0}^i \frac 1k\sum_{l=0}^{k-1}\omega_k^{lj}-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\sum_{i=0}^n\binom ni p^i \sum_{j=0}^i\left(\omega_k^l\right)^j-(p+1)^n
\end{aligned}
\]

这时候可以看到出现了 \(\sum_{j=0}^i\left(\omega_k^l\right)^j\),是一个等比数列求和

\[\begin{aligned}
ans&=\frac 1k \sum_{l=0}^{k-1}\sum_{i=0}^n\binom ni p^i \sum_{j=0}^i\left(\omega_k^l\right)^j-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\sum_{i=0}^n\binom ni p^i \frac{\left(\omega_k^l\right)^{i+1}-1}{\omega_k^l-1}-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\frac{\sum_{i=0}^n\binom ni p^i \left(\omega_k^{l(i+1)}-1\right)}{\omega_k^l-1}-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\frac{\sum_{i=0}^n\binom ni p^i \omega_k^{l(i+1)}-\sum_{i=0}^n\binom ni p^i}{\omega_k^l-1}-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\frac{\sum_{i=0}^n\binom ni p^i \omega_k^{l(i+1)}-(p+1)^n}{\omega_k^l-1}-(p+1)^n\\
\end{aligned}
\]

这下看上去完全推不动了。。。我们再重新审视一下这一个式子,分析一下现在能做到什么复杂度:显然是 \(O(nk)\) 过不了,考虑得把内层 \(O(n)\) 枚举给省掉,而且其类似于二项式定理的形态也激起了我们化简这一部分的欲望。

所以我们把这一段单独拿出来看一下。

\[\begin{aligned}
\sum_{i=0}^n\binom ni p^i \omega_k^{l(i+1)}
\end{aligned}
\]

如果需要逆用二项式定理,需要去掉最后的 \(\omega_k^{l(i+1)}\)。这个幂的表示看起来不太舒服,换成舒服的形式再放回去试一试:

\[\begin{aligned}
&\sum_{i=0}^n\binom ni p^i \omega_k^{l(i+1)}\\
&=\sum_{i=0}^n\binom ni p^i \left(\omega_k^l\right)^{i+1}\\
&=\sum_{i=0}^n\binom ni p^i \left(\omega_k^l\right)^i\omega_k^l\\
&=\omega_k^l\sum_{i=0}^n\binom ni p^i \left(\omega_k^l\right)^i
\end{aligned}
\]

这时可以看到我们将 \(p\) 和 \(\omega_k^l\) 的指数都化成了相同的 \(i\),那我们可以将二者合并起来看,一起放入二项式定理中。

\[\begin{aligned}
ans&=\frac 1k \sum_{l=0}^{k-1}\frac{\omega_k^l\sum_{i=0}^n\binom ni p^i \left(\omega_k^l\right)^i-(p+1)^n}{\omega_k^l-1}-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\frac{\omega_k^l\sum_{i=0}^n\binom ni \left(p \omega_k^l\right)^i-(p+1)^n}{\omega_k^l-1}-(p+1)^n\\
&=\frac 1k \sum_{l=0}^{k-1}\frac{\omega_k^l \left(p \omega_k^l+1\right)^n-(p+1)^n}{\omega_k^l-1}-(p+1)^n\\
\end{aligned}
\]

这时,我们就可以用外层 \(O(k)\) 的复杂度枚举,内层 \(O(\log)\) 级别的复杂度计算快速幂,总复杂度 \(O(k\log n)\) 解决这个问题。

另外注意到一点:在使用等比数列求和公式时,我们没有去验证 \(\omega_k^l-1\ne 0\) 的前提条件;而当 \(l=0\) 时,\(\omega_k^l=0\)。

这时我们可以直接特判

\[\begin{aligned}
&\sum_{i=0}^n\binom ni p^i\sum_{j=0}^i\omega_k^0\\
&=\sum_{i=0}^n\binom ni p^i(i+1)\\
&=\sum_{i=1}^ni\binom ni p^i+(p+1)^n\\
&=\sum_{i=1}^n n\binom {n-1}{i-1} p^i+(p+1)^n\\
&=\sum_{i=0}^{n-1} n\binom {n-1}i p^{i+1}+(p+1)^n\\
&=np\sum_{i=0}^{n-1} \binom {n-1}i p^i+(p+1)^n\\
&=np(p+1)^{n-1}+(p+1)^n\\
\end{aligned}
\]

注:可以看到从有一处开始将 \(\sum\) 的下界改成了 \(i=1\),这是因为当 \(i=0\) 时无贡献

最后再把整个式子弄出来:

\[\begin{aligned}
ans&=\frac 1k \sum_{l=1}^{k-1}\frac{\omega_k^l \left(p \omega_k^l+1\right)^n-(p+1)^n}{\omega_k^l-1}-(p+1)^n+\frac{np(p+1)^{n-1}+(p+1)^n}k\\
\end{aligned}
\]

推式子部分结束。

核心代码

只给出核心代码以供参考,不会实现可以看一看,附有简要注释。数论题还挺好实现罢

typedef long long LL;

const int K=1<<20;
const LL MOD=998244353; LL n,k,p,ik;//ik 是 inv of k
LL omg;//omega
LL ans; LL Pow(LL x,LL b=MOD-2){
LL res=1;
while(b){
if(b&1)
res=res*x%MOD;
x=x*x%MOD;
b>>=1;
}
return res;
} LL G(LL x){//计算 mod 998244353 意义下的 x 次单位元
return Pow(3,(MOD-1)/x);
} int main(){
n=read(),p=read(),ik=Pow(k=read());
omg=G(k);
for(int i=1;i<k;++i){//处理 sigma 内
int ol=Pow(omg,i);
ADD(ans,(ol*Pow((p*ol%MOD+1)%MOD,n)%MOD+MOD-Pow((p+1)%MOD,n))%MOD*Pow(ol+MOD-1)%MOD);
}
ADD(ans,(n*p%MOD*Pow((p+1)%MOD,n-1)%MOD+Pow((p+1)%MOD,n))%MOD);//处理 l=0
ans=ans*ik%MOD;
ADD(ans,MOD-Pow((p+1)%MOD,n));//处理多出来的
printf("%lld\n",ans);
return 0;
}

题解[LuoguP5591]小猪佩奇学数学的更多相关文章

  1. P5591 小猪佩奇学数学

    P5591 小猪佩奇学数学 知识点 二项式定理 \[(x+1)^n=\sum_{i=0}^n\binom nix^i \] 单位根反演 \[[n\mid k]=\frac 1n\sum_{i=0}^{ ...

  2. Luogu5591 小猪佩奇学数学 【单位根反演】

    题目链接:洛谷 \[ Ans=\frac{1}{k}(\sum_{i=0}^n\binom{n}{i}p^ii-\sum_{i=0}^n\binom{n}{i}p^i(i \ \mathrm{mod} ...

  3. P5591-小猪佩奇学数学【单位根反演】

    正题 题目链接:https://www.luogu.com.cn/problem/P5591 题目大意 给出\(n,p,k\)求 \[\left(\sum_{i=0}^n\binom{n}{i}p^i ...

  4. 【题解】P5589 小猪佩奇玩游戏(期望)

    [题解]P5589 小猪佩奇玩游戏(期望) 假设一个点有\(x\)个点(包括自己)可以到达他,他就对答案有\(1/x\)的贡献.这是因为这个点必须被删掉而通过删掉这个点本身删掉这个点的概率是\(1/x ...

  5. 使用canvas 代码画小猪佩奇

    最近不是小猪佩奇很火嘛!!! 前几天 在知乎 看见了别人大佬用python写的 小猪佩奇,  顿时想学 ,可是 自己 没学过python(自己就好爬爬图片,,,,几个月没用 又丢了) 然后 就想画一个 ...

  6. 用CSS画小猪佩奇,你就是下一个社会人!

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:江志耿 | 腾讯TEG网络工程师 我是佩奇,哼,这是我的弟弟乔治,呱呱,这是我的妈妈,嚯,这是我的爸爸,嚯~ 背景 小猪佩奇已经火了好 ...

  7. Python爬虫入门教程 45-100 Charles抓取兔儿故事-下载小猪佩奇故事-手机APP爬虫部分

    1. Charles抓取兔儿故事背景介绍 之前已经安装了Charles,接下来我将用两篇博客简单写一下关于Charles的使用,今天抓取一下兔儿故事里面关于小猪佩奇的故事. 爬虫编写起来核心的重点是分 ...

  8. 运用python绘制小猪佩奇

    用python绘制小猪佩奇 1.打开idle 2.点击File-New Files 3.输入以下代码 1. from turtle import * 2. 3. def nose(x,y):#鼻子 4 ...

  9. python 画个小猪佩奇

    不知道大家小时候有没有学习过logo语言,就是操纵一只小王八,来画各种图案.博主小学微机课就学习了这个,最近发现python的turtle包就是logo语言,所以画个小猪佩奇和大家分享. 代码来自知乎 ...

  10. PS学习之小猪佩奇身上纹,掌声送给社会人

    首先准备素材 用ps首先打开素材一 首先对图片去色 快捷键:shift+Ctrl+u 调整色阶 设置高斯模糊: 另存为psd格式,命名为叠加的对象 再次打开素材一,把佩奇拖入到图层里,并调整大小,旋转 ...

随机推荐

  1. react系列-从0开始搭建一个react项目

    从0开始搭建一个react项目 1.安装脚手架 npm install -g create-react-app 2.创建项目 D: //进入D盘 mkdir ReactDemo //创建ReactDe ...

  2. 前端必备基础知识之--------原生JS发送Ajax请求

    原生JS发送Ajax请求 ajax({ type: 'POST', url: 'http://10.110.120.123:2222', // data: param, contentType: 'a ...

  3. Unity屏幕永远保持为固定分辨率

    Unity屏幕永远保持为固定分辨率 Unity屏幕永远保持为固定分辨率 前言 开题废话 Unity版本 正题: 打开一场景 创建脚本并且编写 挂在脚本到场景摄像机上边 以不同比的分辨率运行程序,并且观 ...

  4. C#反射运行该类下的方法

    Text:反射的类名 s:方法名 data:参数 如果无参则: (string)method.Invoke(obj, null); Type type = typeof(Text); MethodIn ...

  5. 【读书笔记】JS函数式编程指南

    第一章 海鸥群可以合并和繁育 conjoin breed var result = flock_a.conjoin(flock_c).breed(flock_b).conjoin(flo ck_a.b ...

  6. Navicat 15 or 16 永久版本(window和Mac)

    一.下载Navicat Premium 官网https://www.navicat.com.cn/下载最新版本下载安装 链接包含(window激活包和Mac版本,请选择性下载): https://no ...

  7. 2.4.rpx单位有内置的视图容器组件

    所有的视图组件,包括view.swiper等,本身不显示任何可视化元素.它们的用途都是为了包裹其他真正显示的组件. # view 视图容器. 它类似于传统html中的div,用于包裹各种元素内容. 如 ...

  8. P26_wxss - 样式导入

    样式导入 什么是样式导入 使用 WXSS 提供的 @import 语法,可以导入外联的样式表. @import 的语法格式 @import 后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束.示 ...

  9. uboot启动过程 2

    512M内存, 地址范围 [0x80000000, 0xA0000000)  UBOOT原先位置 0x87800000, 移动后的位置0x9FF47000,   也就是最后 700多k,  前面的位置 ...

  10. 数字列表number,目标值target,找到number中两个不同数字之和等于target的数字,输出下标并顺序排列 ----笔试题记录扩展

    一.思路: 输入:数字列表number,目标值target 判断条件:数字列表中两个不同数字相加等于target 输出:符合条件的两个数字的下标,下标顺序排列 方法1: def list(number ...