洛谷 P3711 - 仓鼠的数学题(多项式)
提供一种不太一样的做法。
假设要求的多项式为 \(f(x)\)。我们考察 \(f(x)-f(x-1)\),不难发现其等于 \(\sum\limits_{i=0}^na_ix^i\)
考虑设 \(f(x)=\sum\limits_{i=0}^{n+1}b_ix^i\),那么直接代入 \(x-1\) 并化简可以得到:
f(x-1)&=\sum\limits_{i=0}^{n+1}b_i(x-1)^i\\
&=\sum\limits_{i=0}^{n+1}b_i\sum\limits_{j=0}^i\dbinom{i}{j}(-1)^{i-j}x^j\\
&=\sum\limits_{i=0}^{n+1}(\sum\limits_{j=i}^{n+1}\dbinom{j}{i}(-1)^{j-i}b_j)x^i
\end{aligned}
\]
故
f(x)-f(x-1)&=\sum\limits_{i=0}^{n+1}(\sum\limits_{j=i+1}^{n+1}\dbinom{j}{i}(-1)^{j-i}b_j)x^i
\end{aligned}
\]
根据 \(f(x)-f(x-1)=\sum\limits_{i=0}^na_ix^i\) 可得
\]
按照套路拆组合数:
\]
设
\]
\]
\]
那么上式可以写作:
\]
喜闻乐见的减法卷积,按照套路设
\]
那么有 \(h'\) 为 \(f'\) 与 \(g\),按照常理是一遍求逆就可以解决的事,但是非常悲催的是 \(g_0=0\),因此无法直接求逆,不过注意到对于 \(f'\) 和 \(h'\) 同样有它们的第 \(0\) 项为 \(0\),因此可以将数组全部向前平移一位然后求逆。还有就是原数组是 \(n+1\) 次多项式,平移以后变成了 \(n\) 次多项式,因此我们可以大致确定的 \(f_i\) 只有 \(n+1\) 位,怎么办呢?首先注意到 \(f'_{n+1}=b_0\),也就是待求多项式的常数项,因此我们可以代入 \(x=0\) 求得 \(f'_{n+1}=a_{0}\)。还有就是由于你对 \(f',g\) 卷积是在 \(\bmod x^{n+1}\) 意义下进行,并且 \(g_0=0\),因此理论上来说 \(f'_n\) 是不能通过 \(f'\) 与 \(g\) 卷积为 \(h'\) 这一条件确定的,不过注意到多项式求逆的过程中如果我们固定住 \(f'_0\),那么所有数都可表示为 \(f'_i=v_i·\dfrac{1}{f'_0}\) 的形式,其中 \(v_i\) 为常数,也就是说我们求出来的 \(f'\) 与真正的 \(f'\) 是存在比例关系的,因此我们考虑代入 \(x=1\) 求出待求多项式的系数和,这样即可求出真正的 \(f'\) 相较于我们求出的 \(f'\) 缩放了多少倍,也就可以求出真正的 \(f'\)。
时间复杂度 \(n\log n\)。
const int pr=3;
const int ipr=332748118;
const int MAXN=255555;
const int MAXP=524288;
int n,fac[MAXN+5],ifac[MAXN+5];
void init_fac(int n){
for(int i=(fac[0]=ifac[0]=ifac[1]=1)+1;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
}
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
int rev[MAXP+5];
void NTT(vector<int> &a,int len,int type){
int lg=31-__builtin_clz(len);
for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<len;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=2;i<=len;i<<=1){
int W=qpow((type<0)?ipr:pr,(MOD-1)/i);
for(int j=0;j<len;j+=i){
for(int k=0,w=1;k<(i>>1);k++,w=1ll*w*W%MOD){
int X=a[j+k],Y=1ll*w*a[(i>>1)+j+k]%MOD;
a[j+k]=(X+Y)%MOD;a[(i>>1)+j+k]=(X-Y+MOD)%MOD;
}
}
} if(!~type){
int ivn=qpow(len,MOD-2);
for(int i=0;i<len;i++) a[i]=1ll*a[i]*ivn%MOD;
}
}
vector<int> conv(vector<int> a,vector<int> b){
int LEN=1;while(LEN<a.size()+b.size()) LEN<<=1;
a.resize(LEN,0);b.resize(LEN,0);NTT(a,LEN,1);NTT(b,LEN,1);
for(int i=0;i<LEN;i++) a[i]=1ll*a[i]*b[i]%MOD;
NTT(a,LEN,-1);return a;
}
vector<int> getinv(vector<int> a,int len){
vector<int> b(len,0);b[0]=qpow(a[0],MOD-2);
for(int i=2;i<=len;i<<=1){
vector<int> c(b.begin(),b.begin()+(i>>1));
vector<int> d(a.begin(),a.begin()+i);
c=conv(conv(c,c),d);
for(int j=0;j<i;j++) b[j]=(2ll*b[j]-c[j]+MOD)%MOD;
} return b;
}
vector<int> A,B;
int res[MAXN+5];
int main(){
scanf("%d",&n);init_fac(MAXN);A.resize(n+2);int sum=0;
for(int i=n;~i;i--) scanf("%d",&A[i]),sum=(sum+A[i])%MOD,A[i]=1ll*A[i]*fac[n-i]%MOD;
B.resize(n+2);for(int i=1;i<=n+1;i++) B[i-1]=(i&1)?(MOD-ifac[i]):ifac[i];
int LEN=1;while(LEN<=n+2) LEN<<=1;
A.resize(LEN,0);B.resize(LEN,0);
vector<int> C=conv(A,getinv(B,LEN));
// printf("A: ");for(int i=0;i<n+1;i++) printf("%d%c",A[i]," \n"[i==n]);
// printf("B: ");for(int i=0;i<n+1;i++) printf("%d%c",B[i]," \n"[i==n]);
for(int i=1;i<=n+1;i++) res[i]=1ll*C[n+1-i]*ifac[i]%MOD;
res[0]=A[n];int iv=qpow(res[n+1],MOD-2);
for(int i=1;i<=n+1;i++) res[i]=1ll*res[i]*iv%MOD;
int ssum=0;for(int i=1;i<=n+1;i++) ssum=(ssum+res[i])%MOD;
int mul=1ll*sum*qpow(ssum,MOD-2)%MOD;
for(int i=1;i<=n+1;i++) res[i]=1ll*res[i]*mul%MOD;
for(int i=0;i<=n+1;i++) printf("%d%c",res[i]," \n"[i==n+1]);
return 0;
}
洛谷 P3711 - 仓鼠的数学题(多项式)的更多相关文章
- 洛谷 P3711 仓鼠的数学题 [伯努利数 fft]
P3711 仓鼠的数学题 题意: \[ S_m(x) = \sum_{k=0}^x k^m, 0^0=1\quad 求 \sum_{m=0}^n S_m(x)a_m \] 的答案多项式\(\sum_{ ...
- 洛谷P3711 仓鼠的数学题(伯努利数+多项式求逆)
题面 传送门 题解 如果您不知道伯努利数是什么可以去看看这篇文章 首先我们把自然数幂和化成伯努利数的形式 \[\sum_{i=1}^{n-1}i^k={1\over k+1}\sum_{i=0}^k{ ...
- 洛谷 P3711 仓鼠的数学题【伯努利数+多项式科技】
有个东西叫伯努利数--一开始直接·用第一类斯特林推到自闭 式子来源:https://www.luogu.org/blog/ShadowassIIXVIIIIV/solution-p3711 https ...
- FFT/NTT总结+洛谷P3803 【模板】多项式乘法(FFT)(FFT/NTT)
前言 众所周知,这两个东西都是用来算多项式乘法的. 对于这种常人思维难以理解的东西,就少些理解,多背板子吧! 因此只总结一下思路和代码,什么概念和推式子就靠巨佬们吧 推荐自为风月马前卒巨佬的概念和定理 ...
- 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)
洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...
- 洛谷P4238【模板】多项式求逆
洛谷P4238 多项式求逆:http://blog.miskcoo.com/2015/05/polynomial-inverse 注意:直接在点值表达下做$B(x) \equiv 2B'(x) - A ...
- 洛谷p3398仓鼠找suger题解
我现在爱死树链剖分了 题目 具体分析的话在洛谷blog里 这里只是想放一下改完之后的代码 多了一个son数组少了一个for 少了找size最大的儿子的for #include <cstdio&g ...
- 伯努利数学习笔记&&Luogu P3711 仓鼠的数学题
新科技 Luogu P3711 题意 设$ S_{k,n}$表示$ \displaystyle\sum_{i=0}^n i^k$ 求多项式$\displaystyle\sum_{k=0}^n S_{k ...
- 洛谷P5050 【模板】多项式多点求值
传送门 人傻常数大.jpg 因为求逆的时候没清零结果调了几个小时-- 前置芝士 多项式除法,多项式求逆 什么?你不会?左转你谷模板区,包教包会 题解 首先我们要知道一个结论\[f(x_0)\equiv ...
随机推荐
- Linux信号处理编程
01. 学习目标 了解信号中的基本概念 熟练使用信号相关的函数 了解内核中的阻塞信号集和未决信号集作用 熟悉信号集操作相关函数 熟练使用信号捕捉函数signal 熟练使用信号捕捉函数sigaction ...
- 【数据结构与算法Python版学习笔记】图——拓扑排序 Topological Sort
概念 很多问题都可转化为图, 利用图算法解决 例如早餐吃薄煎饼的过程 制作松饼的难点在于知道先做哪一步.从图7-18可知,可以首先加热平底锅或者混合原材料.我们借助拓扑排序这种图算法来确定制作松饼的步 ...
- Java:异常小记
Java:异常小记 对 Java 中的 异常 ,做一个微不足道的小小小小记 Error 和 Exception 相同点: Exception 和Error 都是继承了 Throwable 类,在 Ja ...
- UltraSoft - Beta - Scrum Meeting 3
20200519会议纪要 Date: May 19th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 暂无 Liuzh 前端 暂无 Kkkk 前端 完成了前端 ...
- [技术博客] Django中文件的保存与访问
[技术博客] Django中文件的保存与访问 在TextMarking项目开发中,数据库需要保存用户上传的文本文档. 原型设计:用户点击上传文本->保存文本->文本发送到后端保存为文件. ...
- 色彩滤镜矩阵(Color Filter Array)
数码相机上的每个象素都带有一个光感应器,用以测量光线的明亮程度.由于光电二极管是只支持单颜色的装置,它不能区别不同波长的光线.因此,数码相机工程师在相机感应器的上部装上了一套镶嵌式的颜色滤镜,一个颜色 ...
- ip_local_port_range 和 ip_local_reserved_ports
问题:启动应用程序时,发现网络端口被占用,原因是什么?如何避免? 原因:Linux 系统设置了随机使用的端口范围 echo "40000 60000" > /proc/. ...
- 21.10.18 test
可可大神出题,四款有趣的游戏推荐,第四个好玩/se T1 loopers \(\color{green}{100}\) 考虑钦定 \(a_1,a_i\) 的位置,固定左边一坨,那么剩下的一坨的 \(\ ...
- ShardingSphere-初见
目录 概述 认识shardingjdbc shardingjdbc功能架构图 认识Sharding-Proxy 三个组件的比较 ShardingJdbc混合架构 ShardingShpere的功能清单 ...
- linux tr
转载:tr命令_Linux tr 命令用法详解:将字符进行替换压缩和删除 (linuxde.net) tr命令 文件过滤分割与合并 tr命令可以对来自标准输入的字符进行替换.压缩和删除.它可以将一组字 ...