链接:https://www.nowcoder.com/acm/contest/109/C
来源:牛客网
给定长度为n的数组a,定义一次操作为:
1. 算出长度为n的数组s,使得s i= (a[1] + a[2] + ... + a[i]) mod 1,000,000,007;
2. 执行a = s;
现在问k次操作以后a长什么样。
1. 算出长度为n的数组s,使得s i= (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 <= ai<= 1,000,000,000)。
输出描述:
一行n个整数表示答案。
示例1
输入
3 1 1 2 3
输出
1 3 6
两种方法,排列组合求路径算出每个数的贡献次数,或者乘以k次全为1的数组
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const ll inf = 0x3f3f3f3f;
/*void dis(int a[], int n){
printf("总数为%d个\n",n);
for(int i = 0; i < n; i++) cout<<a[i]<<", ";
cout<<endl<<"------------------"<<endl;
}*/
const int mx = 2000+10;
const int mod = 1e9+7;
struct no{
ll m[mx];
no(){
memset(m,0,sizeof(m));
}
no &operator * (const no &a)const{
no ans;
for(int i = 0; i < mx; i++)
for(int j = 0; j <= i; j++)
ans.m[i] = (ans.m[i] + m[j]*a.m[i-j]%mod) % mod;
return ans;
}
};
int n,k;
no pow(no a, int b){
if(b == 0)
return a;
no ans;
for(int i = 0; i < n; i++)
ans.m[i] = 1;
while(b){
if(b%2)
ans = ans * a ;
b /= 2;
a = a * a ;
}
return ans;
}
void dis(ll a[]){
for(int i = 0; i < n; i++)
if(i == 0)
printf("%lld",a[i]);
else
printf(" %lld",a[i]);
puts("");
}
int main(){
// int T=10;
no a,b;
scanf("%d%d",&n,&k);
for(int i = 0; i < n; i++)
cin>>a.m[i];
if(k == 0){
dis(a.m);
return 0;
}
for(int i = 0; i < n;i++)
b.m[i] = 1;
no te = pow(b,k-1);
// dis(te.m);
a = a*te;
dis(a.m);
return 0;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const ll inf = 0x3f3f3f3f;
/*void dis(int a[], int n){
printf("总数为%d个\n",n);
for(int i = 0; i < n; i++) cout<<a[i]<<", ";
cout<<endl<<"------------------"<<endl;
}*/
const int mx = 4000+10;
const int mod = 1e9+7;
ll cnt[mx],num[mx],pai[mx];
int n,k;
ll pow(int a, int b){
ll ans = 1;
if(b == 0)
return 1;
while(b){
if(b%2)
ans = ans * a % mod;
b /= 2;
a = 1LL * a * a % mod;
}
return ans;
}
ll cc(int n, int m){
if(m == 0 || n == m)
return 1;
if(m == 1)
return n;
ll ans = 1, cha = n - m;
for(int i = m; i >= 1; i--)
ans = ans * (i+cha) %mod * pow(i,mod-2)%mod;
return ans;
}
/*ll C(ll n,ll m){
if(m<0)
return 0;
if(n-m<m) m = n-m;
ll ans = 1;
for(int i = 1; i <= m; i++)
ans = ans*(n-i+1)%mod*pow(i,mod-2)%mod;
return ans;
}*/
void dis(ll a[]){
for(int i = 1; i <= n; i++)
if(i == 1)
printf("%lld",a[i]);
else
printf(" %lld",a[i]);
puts("");
}
int main(){
int T=10;
scanf("%d%d",&n,&k);
for(int i = 1; i <= n; i++)
cin>>num[i];
if(k == 0){
dis(num);
return 0;
}
for(int i = 0; i < n; i++){
pai[i] = cc(i+k-1,i);
}
memset(cnt,0,sizeof(cnt));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++){
//printf("i = %d j = %d\n",i,j);
//printf("cc= %lld\n",cc(i-j+k-1,i-j));
cnt[i]= (cnt[i] + pai[i-j] * num[j] %mod) % mod;
//printf("cnt[%d] = %lld\n",i,cnt[i]);
}
dis(cnt);
return 0;
}