数字

链接:https://www.nowcoder.com/acm/contest/109/C
来源:牛客网

给定长度为n的数组a,定义一次操作为:
1. 算出长度为n的数组s,使得si= (a[1] + a[2] + ... + a[i]) mod 1,000,000,007;
2. 执行a = s;
现在问k次操作以后a长什么样。

输入描述:

第一行两个整数n,k(1 <= n <= 2000, 0 <= k <= 1,000,000,000);
第二行n个整数表示a数组(0 <= a

i

<= 1,000,000,000)。

输出描述:

一行n个整数表示答案。

先列出前几项找规律
k=1: 1 1,1 1,1,1
k=2: 1 1+1,1 1+1+1,1+1,1
k=3: 1 (1+1)+1,1 (1+1+1)+(1+1)+1,(1+1)+1,1
k=4: 1 (1+1+1)+1,1 (1+1+1+1+1+1)+(1+1+1)+1,(1+1+1+1)+1
用公式表示
k=1: 1 1,1 1,1,1 .... 1,1,1,1,1,1,1,1
k=2: 1 2,1 3,2,1 .... n,n-1,n-2....1
k=3: 1 2*(2+1)/2,1 3*(3+1)/2,2*(2+1)/2,1 .... n*(n+1)/2,(n-1)*(n-1+1)/2,...1
k=4: 1 2*(2+1)*(2+2)/(2*3),1 3*(3+1)*(3+2)/(2*3),2*(2+1)*(2+2)/(2*3),1 .... n*(n+1)*(n+2)/(2*3),(n-1)*n*(n+1)/(2*3),1
所以最终结论是,在进行K次变换后,乘数是有一定关系的。也就是后一项(n)是前一项的 (n+k-1)/(n-1)倍(从分子可以看出来)
可以知道最终第一项乘数一定是1,第二项是k,那么就写一下就可以了.
公式表示那里利用的是数学归纳法:1+2+3+..n=n*(n+1)/2
1*(1+1)/2+2*(2+1)/2+..n*(n+1)/2= n*(n+1)*(n+2)/6
1*(1+1)*(1+2)/6+2*(2+1)*(2+2)/6+..n*(n+1)*(n+2)/6=n*(n+1)*(n+2)*(n+3)/24
............




#include<map> 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e3+88;
const int P=1e9+7;
int inv[N],n,a[N],k,C[N],b[N]; 
void init(){
    inv[1]=1;
    for(int i=2;i<=2000;++i) inv[i]=1LL*inv[P%i]*(P-P/i)%P;
}
int main(){
    scanf("%d%d",&n,&k);
    init();
    C[0]=1;
    for(int i=1;i<=n;++i) C[i]=1LL*C[i-1]*(k+i-1)%P*inv[i]%P;
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    for(int i=1;i<=n;++i) {
        int now=0;
        for(int j=1;j<=i;++j) now=(1LL*C[i-j]*a[j]%P+now)%P;
        b[i]=now;
    }
    for(int i=1;i<=n;++i) printf("%d%c",b[i],i==n?'\n':' '); 
} 

 

posted @ 2018-05-20 16:19  Billyshuai  阅读(179)  评论(0编辑  收藏  举报