単語をコーディングするのが面倒:
トピックリンク:CF622F
紫色のトピックの非常に単純な数は、明らかにいくつかの問題、(ない言及にしていた...
この式では、それは\(K + 1 \)回多項式補間\(K + 2 \)時代のようなの値は、迷惑なプロセスは逆に、私のフェルマーの小定理は明らかである\(O(logPを)\) 、あなたは、私があることを聞いたヨーロッパの拡張機能を使用することができます\(O(K)\)アルゴリズム私は(私も苦手)可能性が低いと感じているようだ。
階乗の前処理、接尾辞配列が複雑さをプロットすることができます前に\(O(klogk + klogp)\) 、この問題は、(高速.JPGを実行することができます)。
\(コード:\)
#include<iostream>
#include<cstdio>
#define mod 1000000007
using namespace std;
long long n,k;
long long fac[1000005],y[1000005];
long long pre[1000005],suf[1000005];
long long ans=0;
long long quickpow(long long a,long long b)
{
long long base=a,ans=1;
while(b)
{
if(b&1) ans=1ll*base*ans%mod;
b>>=1;
base=1ll*base*base%mod;
}
return ans%mod;
}
inline int judge(long long x){if(x&1) return -1;else return 1;}
int main()
{
scanf("%lld%lld",&n,&k);
if(!k)
{
printf("%lld\n",n);
return 0;
}
if(n<=k+2)
{
for(long long i=1;i<=n;i++) ans=(ans+quickpow(i,k))%mod;
printf("%lld\n",ans%mod);
return 0;
}
fac[0]=1,y[0]=0;
pre[0]=1,suf[k+3]=1;
for(int i=1;i<=k+1;i++) fac[i]=1ll*fac[i-1]*i%mod;
for(int i=1;i<=k+2;i++) y[i]=(y[i-1]+quickpow(i,k))%mod;
for(int i=1;i<=k+1;i++) pre[i]=1ll*pre[i-1]*(n-i)%mod;
for(int i=k+2;i>1;i--) suf[i]=1ll*suf[i+1]*(n-i)%mod;
for(int i=1;i<=k+2;i++)
{
long long sum=1;
sum=fac[i-1]*fac[k+2-i]*judge(k+2-i)%mod;
if(judge(k+2-i)==1) sum=1ll*quickpow(sum,mod-2);
else sum=-1ll*(quickpow(-sum,mod-2));
sum=(sum+mod)*y[i]%mod;
sum=sum*pre[i-1]%mod;
sum=sum*suf[i+1]%mod;
ans=(ans+sum)%mod;
}
printf("%lld\n",ans%mod);
return 0;
}
開くことができませんでした(\長い長い)\爆発
(私が知っている^ 3)\(O(K \) ----差分法を行うためのもの)、あなたはポイントの一部を取るだけでなく、正のソリューションよりも深いことができます\(qwq \を)。