• 51nod 1258 序列求和 V4


    题目描述

    T(n) = n^k,S(n) = T(1) + T(2) + ...... T(n)。给出n和k,求S(n)。
     
    例如k = 2,n = 5,S(n) = 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55。
    由于结果很大,输出S(n) Mod 1000000007的结果即可。

    Input

    第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 500)
    第2 - T + 1行:每行2个数,N, K中间用空格分割。(1 <= N <= 10^18, 1 <= K <= 50000)

    Output

    共T行,对应S(n) Mod 1000000007的结果。

    Input示例

    3
    5 3
    4 2
    4 1

    Output示例

    225
    30
    10

    Solution

    很裸的一道自然数幂和问题。 我是用的是拉格朗日插值法
    已知一个最高次项为n的多项式,已知n+1个点就能求得其解析式。
    考虑构造多项式使其满足函数经过(x0,y0),(x1,y1),(x2,y2)...(xn+1,yn+1).

    其中g(x)为n次多项式,显然要使其成立则
    可推得
    把要求的k带入函数中就可求出其自然数幂和

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 
    10 const int N=50005;
    11 const int MOD=1000000007;
    12 
    13 int k,a[N],ny[N],pow[N],p[N],q[N];
    14 LL n;
    15 
    16 int ksm(int x,int y)
    17 {
    18     int ans=1;
    19     while (y)
    20     {
    21         if (y&1) ans=(LL)ans*x%MOD;
    22         x=(LL)x*x%MOD;y>>=1;
    23     }
    24     return ans;
    25 }
    26 
    27 int solve(LL x)
    28 {
    29     if (x<=k+2) return a[x];
    30     x%=MOD;
    31     int w=ksm(pow[k+2],MOD-2);LL ans=0;
    32     p[0]=q[k+3]=1;
    33     for (int i=1;i<=k+2;i++) p[i]=(LL)p[i-1]*(x-i)%MOD;
    34     for (int i=k+2;i>=1;i--) q[i]=(LL)q[i+1]*(x-i)%MOD;
    35     for (int i=1;i<=k+2;i++)
    36     {
    37         (ans+=(LL)a[i]*w%MOD*p[i-1]%MOD*q[i+1])%=MOD;
    38         w=(LL)w*(i-k-2)%MOD*ny[i]%MOD;
    39     }
    40     ans+=ans<0?MOD:0;
    41     return ans;
    42 }
    43 
    44 int main()
    45 {
    46     int T;
    47     scanf("%d",&T);
    48     for (int i=1;i<=50002;i++) ny[i]=ksm(i,MOD-2);
    49     pow[1]=1;
    50     for (int i=2;i<=50002;i++) pow[i]=(LL)pow[i-1]*(1-i)%MOD;
    51     while (T--)
    52     {
    53         scanf("%lld%d",&n,&k);
    54         for (int i=1;i<=k+2;i++) a[i]=a[i-1]+ksm(i,k),a[i]-=a[i]>=MOD?MOD:0;
    55         printf("%d
    ",solve(n));
    56     }
    57     return 0;
    58 }

     

  • 相关阅读:
    qt鼠标事件总结(坐标,跟踪,点击判断)
    从零开始学C++之RTTI、dynamic_cast、typeid、类与类之间的关系uml
    前端篇: 前端演进史
    找一款防文件或文件夹误删除,移动,修改的软件
    yyyy
    盘点我用过的那些网盘(那些年,我们一起玩的网盘)
    Win8/8.1/10获得完整管理员权限的方法
    [置顶] IT老男人读《因为痛,所以叫青春》
    dddd
    用JUNCTION映射文件夹内容 解决多系统跑同一个虚拟机而共享文件夹路径不同的问题
  • 原文地址:https://www.cnblogs.com/patricksu/p/7885943.html
Copyright © 2020-2023  润新知