1. 程式人生 > >51Nod 1161 - Partial Sums(組合數找規律)

51Nod 1161 - Partial Sums(組合數找規律)

題目連結 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1161

【題目描述】
給出一個數組A,經過一次處理,生成一個數組S,陣列S中的每個值相當於陣列A的累加,比如:A = {1 3 5 6} => S = {1 4 9 15}。如果對生成的陣列S再進行一次累加操作,{1 4 9 15} => {1 5 14 29},現在給出陣列A,問進行K次操作後的結果。(每次累加後的結果 mod 10^9 + 7)

Input
第1行,2個數N和K,中間用空格分隔,N表示陣列的長度,K表示處理的次數(2 <= n <= 5000, 0 <= k <= 10^9, 0 <= a[i] <= 10^9)
Output
共N行,每行一個數,對應經過K次處理後的結果。每次累加後mod 10^9 + 7。

Input示例
4 2
1
3
5
6
Output示例
1
5
14
29

【思路】
找規律…,寫出前面幾項可以發現最終第 n n 項的值是原來前 n n a

1 , a 2 . . . a n
a_1,a_2...a_n 的一個多項式,且係數是一個斜著的組合數,最終第 n n 項的答案是 A n s [ n ] = i = 0 n 1 C k 1 + i i × a n i Ans[n]=\sum_{i=0}^{n-1} C_{k-1+i}^{i}×a_{n-i} 組合數可以用下面的式子遞推, C n + 1 m + 1 = C n m × n + 1 m + 1 C_{n+1}^{m+1}=C_{n}^{m}×\frac{n+1}{m+1}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=5005;
const int mod=1e9+7;

int n,k;
int a[maxn];
ll inv[maxn];
ll ans[maxn];

void getInv(ll p){
    inv[1]=1;
    for(int i=2;i<maxn;i++){
        inv[i]=(p-(p/i))*inv[p%i]%p;
    }
}

int main(){
	getInv(mod);
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	for(int i=1;i<=n;++i){
		ll C=1;
		for(int j=0;j<=i-1;++j){
			ans[i]=(ans[i]+C*a[i-j]%mod)%mod;
			if(j<i-1) C=C*(k+j)%mod*inv[j+1]%mod;
		}
	}
	for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
	return 0;
}