51nod 1161 Partial Sums
给出一个数组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
————————————————————————
这题我们单独考虑矩阵乘法 我们发现 这个矩阵大概是长这样的
1 1 1 .... 1
0 1 1 ..... 1
0 0 1 ..... 1
0 0 0 ..... 1
然后观察发现 我们可以通过第一行直接推出下面的所有行
我们再考虑发现第一行每一位满足一定的条件
第i个=C(k+i-1,i-1)然后就可以nlogn+n^2直接推出最后的矩阵
然后在n^2矩阵乘法直接推出答案辣
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long const int M=5e3+7,mod=1e9+7; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k; int s[M],ans[M]; int b[M][M]; LL inv(LL a,LL b){ LL ans=1; while(b){ if(b&1) ans=ans*a%mod; b>>=1; a=a*a%mod; }return ans; } int main(){ n=read(); k=read()-1; for(int i=1;i<=n;i++) s[i]=read()%mod; b[1][1]=1; for(int i=1;i<n;i++) b[1][i+1]=1LL*b[1][i]*(k+i)%mod*inv(i,mod-2)%mod; //for(int i=1;i<=n;i++) printf("[%d] ",b[1][i]); puts(""); for(int i=2;i<=n;i++){ int cnt=0; for(int j=i;j<=n;j++) b[i][j]=b[1][++cnt]; } // for(int i=1;i<=n;i++,puts("")) for(int j=1;j<=n;j++) printf("[%d] ",b[i][j]); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) ans[i]=(ans[i]+1LL*s[j]*b[j][i]%mod)%mod; for(int i=1;i<=n;i++) printf("%d\n",ans[i]); return 0; }