码迷,mamicode.com
首页 > 其他好文 > 详细

CF622F:The Sum of the k-th Powers

时间:2020-01-03 23:15:40      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:res   class   ret   str   --   mod   lin   bit   多项式   

CF622F:The Sum of the k-th Powers

题意:

  • \(\sum_{i=1}^ni^k\),结果模\(1e9+7\)

思路:

  • 拉格朗日插值法。
  • 看大部分题解发现说是\(\sum_{i=1}^ni^k\)是一个\(k+1\)次多项式,可是我实在是看不出来,所以接下来证明一下。

  • 首先看一个等差数列:
    • \(1,2,3,...,n\)
  • 之后做差分操作:
    • \(2-1,3-2,...,n-(n-1)\).
    • \(1,1,1,...,1\).
  • 对于这样一个数列,我们称之为常数数列。

  • 所以我们现在有等差数列:
    • \(a_1,a_2,...,a_n\).
  • 做差分后
    • \(a_2-a_1,a_3-a_2,...,a_n-a_{n-1}\).
    • \(b_1,...,b_{n-1}\).
  • 我们知道\(b_i=d\),其中\(d\)为公差。
  • 那当然此时的\(\{a\}\)是等差数列,所以\(b_i\)会全部相等,但假如说\(\{a\}\)是一般的数列呢?
  • 同样做差,我们得到\(\{b\}\)序列,称之为数列\(\{a\}\)的阶差数列。
  • 那么再对数列\(\{b\}\)做差分,就可以得到二阶阶差数列。
  • 同样的我们可以有三阶,四阶...。
  • 如果\(\{a\}\)\(p\)阶差数列是一个非\(0\)的常数数列,那么就称数列\(\{a\}\)\(p\)阶等差数列。

定理:

  • 数列\(\{a\}\)是一个\(p\)阶等差数列的充要条件是通项\(a_x\)\(x\)的一个\(p\)次多项式。
简单的证明:
  • 已知一个数列\(\{a\}\)是一个\(p\)阶等差数列,设\(\{a\}\)的通项\(a_x\)是一个关于\(x\)\(v\)次多项式,即\(f(x)=\sum_{i=0}^vu_i*x^i\)。其中\(u_i\)\(x^i\)的系数。
  • 做一阶差分可得:
    • \(\Delta f(x)=f(x+1)-f(x)=\sum_{i=0}^vu_i*(x+1)^i-\sum_{i=0}^vu_i*x^i\).
  • 只考虑\(x^v\)
    • \(u_v*(x+1)^v-u_v*x^v\).
  • 二项式定理展开\((x+1)^v\),因为只考虑\(x^v\),所以\(x^v\)的系数为\(1\)
    • \(u_v*x^v-u_v*x^v=0\).
  • 所以可知,在一次差分后,\(x^v\)项被消除了,所以我们知道每做一次差分,得到数列的通项的多项式次数会减一
  • 又因为\(\{a\}\)是一个\(p\)阶等差数列,所以数列\(\{a\}\)在做\(p\)次差分后,会得到一个\(0\)次多项式,也就是常数。

回到题目

  • 此时序列\(\{a\}\)为:
    • \(\sum_{i=1}^0i^k,\sum_{i=1}^1i^k,\sum_{i=1}^2i^k,...,\sum_{i=1}^ni^k\).
  • 差分后有:
    • \(\sum_{i=1}^1i^k-\sum_{i=1}^0i^k,\sum_{i=1}^2i^k-\sum_{i=1}^1i^k,...,\sum_{i=1}^ni^k-\sum_{i=1}^{n-1}i^k\).
  • 也就是\(1^k,2^k,...,n^k\)
  • 这个数列的通项为\(f(x)=x^k\),是一个\(k\)次多项式。
  • 题目要求\(\sum_{i=1}^ni^k\),又知差分序列求前缀和为原序列。
  • 所以原序列为所求。
  • 我们又知每次差分后数列通项的多项式次数会减一,差分序列的次数为\(k\),所以数列\(\{a\}\)是一个关于\(n\)\(k+1\)次多项式。
  • 所以我们只需要插值搞出这个\(k+1\)次多项式即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 1e6 + 10;
ll pre[maxn], suf[maxn], fac[maxn];
ll n, k, ans;
ll qmi(ll a, ll b)
{
    ll res = 1; res %= mod;
    while(b)
    {
        if(b&1) res = res*a%mod;
        a = (a*a)%mod;
        b >>= 1;
    } return res % mod;
}

void init()
{
    pre[0] = suf[k+3] = fac[0] = 1;
    for(int i = 1; i <= k+2; i++)
        pre[i] = pre[i-1]*(n-i) % mod;
    for(int i = k+2; i >= 1; i--)
        suf[i] = suf[i+1]*(n-i) % mod;
    for(int i = 1; i <= k+2; i++)
        fac[i] = fac[i-1]*i % mod;
}

void Lagrange()
{
    ll y = 0;
    for(int i = 1; i <= k+2; i++)
    {
        y = (y + qmi(i, k)) % mod;
        ll a = pre[i-1]*suf[i+1] % mod;
        ll b = fac[i-1]*((k-i)&1 ? -1ll : 1ll)*fac[k+2-i] % mod;
        ans = (ans + y*a%mod * qmi(b, mod-2)) % mod;
    } cout << (ans + mod) % mod << endl;
}

int main()
{
    scanf("%lld%lld", &n, &k);
    init(); Lagrange();
    return 0;
}

CF622F:The Sum of the k-th Powers

标签:res   class   ret   str   --   mod   lin   bit   多项式   

原文地址:https://www.cnblogs.com/zxytxdy/p/12147208.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!