1. 程式人生 > >CF 622F The Sum of the k-th Powers——拉格朗日插值

CF 622F The Sum of the k-th Powers——拉格朗日插值

題目:http://codeforces.com/problemset/problem/622/F

發現 sigma(i=1~n) i 是一個二次的多項式( (1+n)*n/2 ),sigma(i=1~n) i^2 是一個三次的多項式,所以 sigma(i=1~n) i^k 是一個k+1次的多項式。用拉格朗日插值就能做了。

注意別弄成 n^2 的。其實就是移動一個位置的時候乘一個數除以一個數,這樣的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define
ll long long using namespace std; const int N=1e6+5,mod=1e9+7; int n,k,a[N],inv[N],ans; int pw(int x,int k) {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;} void upd(int &x){x>=mod?x-=mod:0;} int main() { scanf("%d%d",&n,&k); int lm=k+2; if(n<=lm) {
for(int i=1;i<=n;i++)a[i]=a[i-1]+pw(i,k),upd(a[i]); printf("%d\n",a[n]); return 0; } for(int i=1;i<=lm;i++)inv[i]=pw(i,mod-2); int s0=1; for(int i=1;i<=lm;i++)s0=(ll)s0*(n-i)%mod; int s1=1,fx=((lm-1)&1?-1:1); for(int i=2;i<=lm;i++)s1=(ll)s1*(i-1)%mod; a[1]=1; ans=(ll)s0*pw(n-1
,mod-2)%mod*fx*pw(s1,mod-2)%mod*a[1]%mod; for(int i=2;i<=lm;i++) { a[i]=a[i-1]+pw(i,k);upd(a[i]); fx=-fx; s1=(ll)s1*(i-1)%mod*inv[lm-i+1]%mod; ans=(ans+(ll)s0*pw(n-i,mod-2)%mod*fx*pw(s1,mod-2)%mod*a[i])%mod; } printf("%d\n",ans<0?ans+mod:ans); return 0; }