【ybt金牌导航8-3-4】【luogu CF622F】K次方求和 / The Sum of the k-th Powers(拉格朗日插值)

K次方求和 / The Sum of the k-th Powers

题目链接:ybt金牌导航8-3-4 / luogu CF622F

题目大意

给你 n,k,要你求 i=1~n 每个 i^k 的和。

思路

首先重新给式子:
i=1nik

然后这个东西你设成 f(n),它其实是一个 k+1 次的多项式。

这里简单的证明一下:
你可以通过差分它得到 ik,然后接着每次差分就依次变成:
ik1,ik2,...

最后会变成 i0=1,即全部都是 1 的数组。(这个是 0 次的)
所以反过来就是前缀和,每次次数加一,加到 ikk 次,再前缀就是 k+1 次了。

然后你就直接用拉格朗日插值,你任意取值就直接取 1k+2 的值,然后用连续的那种搞可以了。

代码

#include<cstdio> #define ll long long #define mo 1000000007 using namespace std; ll n, k, y[1000003], jc[1000003]; ll ans, now, pre[1000003], suf[1000003]; ll ksm(ll x, ll y) { ll re = 1; while (y) { if (y & 1) re = re * x % mo; x = x * x % mo; y >>= 1; } return re; } ll work(int k, int n) { pre[0] = 1; for (int i = 1; i <= n; i++) pre[i] = pre[i - 1] * (k - i + mo) % mo; suf[n + 1] = 1; for (int i = n; i >= 1; i--) suf[i] = suf[i + 1] * (k - i + mo) % mo; jc[0] = 1; for (int i = 1; i <= n; i++) jc[i] = jc[i - 1] * i % mo; ll ans = 0; for (int i = 1; i <= n; i++) { ans = (ans + y[i] * pre[i - 1] % mo * suf[i + 1] % mo * ksm(jc[i - 1] * jc[n - i] % mo * (((n - i) & 1) ? mo - 1 : 1) % mo, mo - 2) % mo) % mo; } return ans; } int main() { scanf("%lld %lld", &n, &k); for (int i = 1; i <= k + 2; i++) { now = (now + ksm(i, k)) % mo; y[i] = now; } printf("%lld", work(n, k + 2)); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_8-3-4.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(40)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示