【清华冬令营2018模拟】距离

题解

Description
【清华冬令营2018模拟】距离_第1张图片

Input
这里写图片描述

Output
这里写图片描述

Sample Input

输入1:
1 1
输入2:
2 2

Sample Output

输出1:
2
输出2:
40

Data Constraint

【清华冬令营2018模拟】距离_第2张图片

题解

由题意可列出:

ans=ki=1ikj=1Cjk(2i1)kj2j
由二项式定理:
(a+b)n=ni=0Cinaibni
原式等价于
ans=ni=1i[(2i+1)k(2i1)k]
不难发现这个式子的指数是k+1级别的
所以使用拉格朗日插值法

贴代码

#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define ll long long

using namespace std;

const int maxn=1e6+5,md=1e9+7;

int yu[maxn];
int i,j,k,l,m,n,x,y,ans,p,tot,mi,bi;
int c1,c2;

int quickmi(int x,int y){
    int t1=1,t2=x;
    while (y){
        if ((y & 1)==1) t1=(1ll*t1*t2)%md;
        t2=(1ll*t2*t2)%md;
        y=y/2;
    }
    return t1;
}

int main(){
    freopen("dis.in","r",stdin);
    freopen("dis.out","w",stdout);
    scanf("%d%d",&k,&n);
    fo(i,1,k+2) yu[i]=(1ll*i*(md+quickmi(2*i+1,k)-quickmi(2*i-1,k))%md)%md;
    fo(i,2,k+2) yu[i]=(yu[i]+yu[i-1])%md;
    c1=c2=1;
    if (n<=k+2){
        printf("%d",yu[n]);
        return 0;
    }
    fo(i,2,k+2){
        c1=(1ll*c1*(n-i))%md;
        c2=(1ll*c2*(1-i))%md;
    }
    ans=(ans+yu[1]*((1ll*c1*quickmi(c2,md-2))%md))%md;
    mi=-k-1; bi=1;
    fo(i,2,k+2){
        c1=((ll)c1*quickmi(n-i,md-2))%md;
        c1=((ll)c1*(n-i+1))%md;
        c2=((ll)c2*quickmi(mi,md-2))%md;
        c2=((ll)c2*bi)%md;
        mi++; bi++; if (mi==0) mi++;
        ans=(ans+yu[i]*(((ll)c1*quickmi(c2,md-2))%md))%md;
    }
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(数学)