这题黑的丫!怎么会掉紫呢!

noteskey

伯努利数... 这里 有介绍哟~ 写的非常详细呢~

反正这题就是推柿子...

另外就是黈力算法的运用 QWQ

我们令 \(ANS(x)\) 为答案多项式,那么这个多项式可以这么求:

(下面我们定义 \(S(n,k)\) 为自然幂和函数(不是第二类斯特林数!),即 \(\sum_{i=0}^{ n} i^k\))

\[\begin{aligned}ANS(x)=& \sum_{k=0}^{n} S_k (x) a_k \\ =& \sum_{k=0}^{n} (S(x,k)+x^k) a_k \\ =& \sum_{k=0}^n a_k \Big( x^k +{1\over k+1} \sum_{i=0}^k \begin{pmatrix} k+1\\i \end{pmatrix} B_i x^{k+1-i}\Big) \\ =& \sum_{k=0}^n a_k \Big( x^k + k! \sum_{i=0}^k {B_i\over i!} {x^{k+1-i} \over (k+1-i)! }\Big) \\ =& \sum_{k=0}^n a_k x^k + \sum_{k=0}^n a_k k! \sum_{i=0}^k {B_i\over i!} {x^{k+1-i} \over (k+1-i)! } \\ =& \sum_{i=0}^n a_i x^i + \sum_{i=1}^{n+1} x^i i! \sum_{k=i-1}^{n} a_k k!{B_{k+1-i}\over (k+1-i)!} \end{aligned}\]

然后感觉做不下去了呢...后面虽说像是卷积的形式然鹅根本就不是卷积呢QWQ

首先,我们看着表达式太长了,于是乎把表达式换成一个函数:

\[\begin{aligned}f(i)=&~a_ii! \\g(i) =&~{B_i \over i!} \end{aligned}\]

那么原来的式子就是:

\[ANS=\sum_{i=0}^n a_i x^i + \sum_{i=1}^{n+1} x^i i! \sum_{k=i-1}^{n} f(k)g(k+1-i) \]

这样的话,我们就更加清晰的发现后面的式子不是卷积的形式了 XD

那么我们令 \(gr(i)=g(n-i)\) (也就是翻转多项式)

然后原来的式子就是:

\[ANS=\sum_{i=0}^n a_i x^i+ \sum_{i=1}^{n+1} x^i i! \sum_{k=i-1}^{n} f(k)gr(n+i-k-1) \]

发现这里就是最高项改成 \(n+i\) 项的卷积了,于是我们发现 要计算后面的 \(\sum_{k=i-1}^n\) 什么的算出来的是 \(f* gr\) 的第 \((n+i-1)\) 项

于是我们把 \(f* gr\) 的多项式求出来,拿第 \((n-i+1)\) 项乘上 \(i!\) ,再加上 \(a_i\) 就是最后多项式的第 i 项答案了

好像没有黑题难度? 前提你得知道伯努利数这玩意儿丫! 【雾

而且这个推导过程...好像比 shadowice 巨巨的短很多丫...【小声

code

不知道为什么不开 Ofast 跑得比开了快... 600ms +

//by Judge
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define ll long long
using namespace std;
const int mod=998244353;
const int iG=332748118;
const int M=1<<19|3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int mul(int x,int y){return 1ll*x*y%mod;}
inline int dec(int x,int y){return x<y?x-y+mod:x-y;}
inline int inc(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int read(){ int x=0,f=1; char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr=' '){if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,limit; arr fac,ifac,a,B,C,r;
inline int qpow(int x,int p=mod-2,int s=1){for(;p;p>>=1,x=mul(x,x)) if(p&1) s=mul(s,x); return s;
}
inline void init(int n){ int len=-1;for(limit=1;limit<=n;limit<<=1) ++len;fp(i,0,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<len);
}
inline void NTT(int* a,int tp){ fp(i,0,limit-1) if(i<r[i]) swap(a[i],a[r[i]]);for(Rg int mid=1;mid<limit;mid<<=1){ Rg int I=mid<<1,Gn=qpow(tp?3:iG,(mod-1)/I);for(Rg int j=0,x;j<limit;j+=I) for(Rg int k=0,g=1;k<mid;++k,g=mul(g,Gn))x=mul(a[j+k+mid],g),a[j+k+mid]=dec(a[j+k],x),a[j+k]=inc(a[j+k],x);} if(tp) return ; int inv=qpow(limit); fp(i,0,limit-1) a[i]=mul(a[i],inv);
}
void get_inv(int* a,int* b,int n){if(n==1) return b[0]=qpow(a[0]),void(); static int c[M],d[M];get_inv(a,b,n>>1),init(n); for(int i=0;i<n;++i) c[i]=a[i],d[i]=b[i];for(int i=n;i<limit;++i) c[i]=d[i]=0; NTT(c,1),NTT(d,1);fp(i,0,limit-1) c[i]=mul(c[i],mul(d[i],d[i])); NTT(c,0);fp(i,0,n-1) b[i]=dec(inc(b[i],b[i]),c[i]);
}
inline void prep(int len){ B[0]=ifac[0]=ifac[1]=fac[0]=fac[1]=1;fp(i,2,len) ifac[i]=mul(mod-mod/i,ifac[mod%i]);fp(i,2,len) ifac[i]=mul(ifac[i-1],ifac[i]),fac[i]=mul(fac[i-1],i);get_inv(ifac+1,B,len);
}
int main(){ n=read();for(limit=1;limit<=n;limit<<=1); prep(limit);fp(i,0,n) a[i]=read(),C[i]=mul(a[i],fac[i]);reverse(B,B+1+n),init(n<<1|1);fp(i,n+1,limit-1) B[i]=C[i]=0; NTT(B,1),NTT(C,1);fp(i,0,limit-1) B[i]=mul(B[i],C[i]); NTT(B,0);fp(i,0,n+1) B[n+i-1]=mul(B[n+i-1],ifac[i]);fp(i,0,n) B[n+i-1]=inc(B[n+i-1],a[i]);print(a[0]); fp(i,1,n+1) print(B[n+i-1]);return sr[CCF]='\n',Ot(),0;
}

more...

其实我们只需要用另外一种伯努利数,就可以让推导更加简洁(没简洁多少,代码复杂度也基本没变的说)

这个伯努利数就是之前提到的那篇博客里面讲的 \(B^+\),这个伯努利数列满足的性质更加适合做这道题...

于是我们令 \(B=B^+\), 然后重推一遍:

(其实没必要,给个代码就 OJBK 了? 【滑稽)

\[\begin{aligned}ANS(x)=& \sum_{k=0}^{n} S_k (x) a_k \\ =& \sum_{k=0}^{n} S^+(x,k) a_k \\ =& \sum_{k=0}^n a_k \Big( {1\over k+1} \sum_{i=0}^k \begin{pmatrix} k+1\\i \end{pmatrix} B_i x^{k+1-i} \Big) \\ =& \sum_{k=0}^n a_k k! \sum_{i=0}^k {B_i\over i!} {x^{k+1-i} \over (k+1-i)! } \\ =& \sum_{i=1}^{n+1} x^i i! \sum_{k=i-1}^{n} a_k k!{B_{k+1-i}\over (k+1-i)!} \end{aligned}\]

依然令:

\[\begin{aligned}f(i)=&~a_ii! \\g(i) =&~{B_i \over i!} \\g_r(i)=&~g(n-i)\end{aligned}\]

(注意这里的 \(B_i\) 就是 \(B_i^+\) )

\[ANS=\sum_{i=1}^{n+1} x^i i! \sum_{k=i-1}^{n} f(k)gr(n+i-k-1) \]

同样的,把 \(f* g_r\) 的第 \((n-i+1)\) 项乘上 \(i!\) 就是最后的答案了 ,不同的就是这里不需要再加上 \(a_i\) XD

code*2

代码...可谓没有什么区别

//by Judge
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define ll long long
using namespace std;
const int mod=998244353;
const int iG=332748118;
const int M=1<<19|3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int mul(int x,int y){return 1ll*x*y%mod;}
inline int dec(int x,int y){return x<y?x-y+mod:x-y;}
inline int inc(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int read(){ int x=0,f=1; char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr=' '){if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,limit; arr fac,ifac,a,B,C,r;
inline int qpow(int x,int p=mod-2,int s=1){for(;p;p>>=1,x=mul(x,x)) if(p&1) s=mul(s,x); return s;
}
inline void init(int n){ int len=-1;for(limit=1;limit<=n;limit<<=1) ++len;fp(i,0,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<len);
}
inline void NTT(int* a,int tp){ fp(i,0,limit-1) if(i<r[i]) swap(a[i],a[r[i]]);for(Rg int mid=1;mid<limit;mid<<=1){ Rg int I=mid<<1,Gn=qpow(tp?3:iG,(mod-1)/I);for(Rg int j=0,x;j<limit;j+=I) for(Rg int k=0,g=1;k<mid;++k,g=mul(g,Gn))x=mul(a[j+k+mid],g),a[j+k+mid]=dec(a[j+k],x),a[j+k]=inc(a[j+k],x);} if(tp) return ; int inv=qpow(limit); fp(i,0,limit-1) a[i]=mul(a[i],inv);
}
void get_inv(int* a,int* b,int n){if(n==1) return b[0]=qpow(a[0]),void(); static int c[M],d[M];get_inv(a,b,n>>1),init(n); for(int i=0;i<n;++i) c[i]=a[i],d[i]=b[i];for(int i=n;i<limit;++i) c[i]=d[i]=0; NTT(c,1),NTT(d,1);fp(i,0,limit-1) c[i]=mul(c[i],mul(d[i],d[i])); NTT(c,0);fp(i,0,n-1) b[i]=dec(inc(b[i],b[i]),c[i]);
}
inline void prep(int len){B[0]=ifac[0]=ifac[1]=fac[0]=fac[1]=1;fp(i,2,len) ifac[i]=mul(mod-mod/i,ifac[mod%i]);fp(i,2,len) ifac[i]=mul(ifac[i-1],ifac[i]);fp(i,2,len) fac[i]=mul(fac[i-1],i);get_inv(ifac+1,B,len); B[1]=mod-B[1];
}
int main(){ n=read();for(limit=1;limit<=n;limit<<=1); prep(limit);fp(i,0,n) a[i]=read(),C[i]=mul(a[i],fac[i]);reverse(B,B+1+n),init(n<<1|1);fp(i,n+1,limit-1) B[i]=C[i]=0; NTT(B,1),NTT(C,1);fp(i,0,limit-1) B[i]=mul(B[i],C[i]); NTT(B,0);fp(i,0,n+1) B[n+i-1]=mul(B[n+i-1],ifac[i]);print(a[0]); fp(i,1,n+1) print(B[n+i-1]);return sr[CCF]='\n',Ot(),0;
}

转载于:https://www.cnblogs.com/Judge/p/10727652.html

题解P3711:【仓鼠的数学题】相关推荐

  1. P3711 仓鼠的数学题(伯努利数)

    P3711 仓鼠的数学题 有关伯努利数的知识可以看我的上一篇题解链接(写的超详细). F(x)=∑k=0nSk(x)ak原本定义的Sk(x)=∑i=0xik根据伯努利数的定义Sk′(x)=∑i=0x− ...

  2. 伯努利数(详解 + 例题 :P3711 仓鼠的数学题)

    伯努利数 定义Sk(n)=∑i=0n−1ikS_k(n) = \sum\limits_{i = 0} ^{n - 1} i ^ kSk​(n)=i=0∑n−1​ik. 从二项式出发 (0+1)k+1= ...

  3. 牛客网CSP-S提高组赛前集训营1题解(仓鼠的石子游戏 [博弈论] + 乃爱与城市的拥挤程度 [树上DP] + 小w的魔术扑克[dfs + 离线])

    文章目录 T1:仓鼠的石子游戏 题目 题解 代码实现 T2:乃爱与城市拥挤程度 题目 题解 代码实现 T3:小w的魔术扑克 题目 题解 代码实现 T1:仓鼠的石子游戏 题目 仓鼠和兔子被禁止玩电脑,无 ...

  4. 【题解】简单的数学题-题解

    本贴不适宜大佬食用 题目来源:ARC111A 题目大意 给出 n n n和 m m m,求 ⌊ 1 0 n m ⌋ % m \lfloor{\frac{10^n}{m}}\rfloor \% m ⌊m ...

  5. 2021百度之星初赛第一场部分题解

    写在前面 几个家长要求我写一些2021百度之星初赛第一场的题解. 1003 鸽子 原题链接 https://acm.hdu.edu.cn/showproblem.php?pid=6998 http:/ ...

  6. 伯努利数学习笔记的说...

    经过一天的学习,我们发现伯努利数是个非常有用 (个屁) 的数列 定义 但是...伯努利数是什么呢?我们先给伯努利数一个定义: 令 \(B(i)\) 表示 伯努利数第 i 项,那么有: \[\sum_{ ...

  7. 1103 缘分数(20分)-- 测试点1、测试4

    1103 缘分数 所谓缘分数是指这样一对正整数 a 和 b,其中 a 和它的小弟 a−1 的立方差正好是另一个整数 c 的平方,而 c 正好是 b 和它的小弟 b−1 的平方和.例如 8 3 − 7 ...

  8. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

  9. JZOJ 3736. 数学题(math) 题解

    JZOJ 3736. 数学题(math) 题解 题意: 给定 a ⃗ , b ⃗ \vec a , \vec b a ,b , 问 对 于 任 意 x , y ∈ Z , 且 x , y 不 同 时 ...

最新文章

  1. 腾讯云CentOS 7 上安装Nginx
  2. what is ssao
  3. Mysql设置忽略大小写
  4. android 自定义桌面图标大小设置,手机桌面图标尺寸可以改?OriginOS重新定义个性化...
  5. 《Adobe Premiere Pro CC经典教程》——6.2 节目监视器控件
  6. java 后台设置cookie
  7. SkipList A Probabilistic Alternative to Balanced Trees
  8. Caused by: java.lang.IllegalStateException: Process 9461 exceeded cursor quota 100, will kill it
  9. Catfish任意代码执行漏洞 0day
  10. c语言编程坦克图案,用C语言的图像函数画一个简单的坦克图样
  11. Reggie外卖项目 —— 项目开发整体介绍
  12. php怎么设置段落之间的距离,html中P标签段落与CSS段落间距距离调整
  13. 可免费编辑 PDF 内容的 7 大 PDF 编辑工具
  14. 中序遍历二叉树的非递归实现(利用栈)
  15. 夜神模拟器 版本下载
  16. Android手机号码获取问题
  17. javascript特效模拟marquee
  18. 基于机器学习的航空公司客户价值分析与流失预测
  19. APP和小程序有什么区别?
  20. 如何在谷歌浏览器上,查看手机客户端页面

热门文章

  1. 一般用法(IPG写)
  2. 假如你有20万用来创业,你最想进入什么行业?
  3. 手机正在录音怎么隐藏
  4. 50岁,投资理财方面接触较少,手上有280万,该如何操作?
  5. 螃蟹为什么横着走,今天为大家介绍为什么螃蟹横着走
  6. 为什么我们一直赚不到钱?
  7. 嫌贫爱富,是人性,也是典型的消费心理
  8. 初创公司要严控会议时长,日会5-15分钟,周会不超30分钟
  9. OpenStack 的诞生
  10. win10家庭版与专业版有什么区别?