斜着的杨辉三角
链接: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长什么样。
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);i
第二行n个整数表示a数组(0 <= a
<= 1,000,000,000)。
输出描述:
一行n个整数表示答案。
示例1
输入
3 1 1 2 3
输出
1 3 6
示例2
输入
5 0 3 14 15 92 6
输出
3 14 15 92 6
题意 :不断的累加当前项到第一项的和,重复此过程K次,输出最后的每个位置的答案
思路分析:先考虑一个一个数的情况
观察看就是个斜的杨辉三角,由组合数递推式可以求出来每一项,最后在相应的累加就可以
代码示例 :
const ll mod = 1e9+7; ll f[2005]; ll n, k; ll pre[2005]; ll ans[2005]; ll qpow(ll x, ll cnt){ ll ans = 1; while(cnt > 0){ if (cnt&1) ans = (ans*x)%mod; x = (x*x)%mod; ans %= mod; cnt >>= 1; } return ans; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n >>k; for(ll i = 1; i <= n; i++) scanf("%lld", &pre[i]); int pt = 1; f[1] = 1; ll nn = k; for(ll i = 1; i < n; i++){ ll x = 1; for(ll j = 1; j <= i; j++){ x *= ((nn-j+1)*qpow(j, mod-2))%mod; x %= mod; } f[i+1] = x; nn++; } //for(ll i = 1; i <= n; i++) printf("%d ", f[i]); for(ll i = 1; i <= n; i++){ int pos = i; for(ll j = 1; j <= (n-i+1); j++){ ans[pos] += (f[j]*pre[i])%mod; ans[pos++] %= mod; } } for(ll i = 1; i <= n; i++) printf("%lld%c", ans[i]%mod, i==n?'\n':' '); return 0; }
东北日出西边雨 道是无情却有情