WUST OJ-1288:Sequence(矩阵快速幂)

1288: Sequence

Time Limit: 3 Sec   Memory Limit: 128 MB   64bit IO Format: %lld
Submitted: 20   Accepted: 4
[ Submit][ Status][ Web Board]

Description

YXH is very fond of the sequence. One day he found a very interesting sequence. At time T, a sequence A is A(1) ,A(2) ,…,A(n) After one second (at time T + 1), the sequence will become A(1) ,A(2)+2A(1) ,A(3)+2A(2)+3A(1) ,…,A(n)+2A(n-1)+…+nA(1) YXH wants to know the sequence at time K. Can you solve this problem?

Input

There are multiple test cases. For each case, the first line contains a number N indicating the length of the sequence. The second line contains N numbers indicating the sequence in time 0. The third line contains a number K as description above. Technical Specification 1 <= N <= 300, 1 <= K <= 1,000,000,000 The absolute value each number in the sequence will not exceed 300.

Output

For each case, print the sequence at time K in one line. Since the answer could be very large, you should output the answer module 1,000,000,007

Sample Input 


3

1 2 3

2

Sample Output

1 6 21


思路:矩阵快速幂。但是如果单纯的n*n*n*log(k)的时间复杂度会TLE。打表发现友矩阵满足a[i][j]=a[i-1][j-1](1<=i,j)。那么可以算出第一行,然后n^2推出其它的数。复杂度n*n*log(k)。

#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
typedef long long ll;
struct lenka
{
    int a[300][300];
};
ll f[300],d[300];
int n;
lenka cla(const lenka& a,const lenka& b)
{
    lenka c;
    memset(c.a,0,sizeof c.a);
    for(int j=0;j<n;j++)
    {
        for(int k=0;k<=j;k++)c.a[0][j]=(c.a[0][j]+(ll)a.a[0][k]*(ll)b.a[k][j]%MOD)%MOD;
    }
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(j==0)c.a[i][j]=0;
            else c.a[i][j]=c.a[i-1][j-1];
        }
    }
    return c;
}
lenka POW(int k)
{
    lenka a,res;
    memset(a.a,0,sizeof a.a);
    memset(res.a,0,sizeof res.a);
    for(int i=0;i<n;i++)a.a[i][i]=1;
    for(int i=0;i<n;i++)
    {
        for(int j=i;j<n;j++)res.a[i][j]=j-i+1;
    }
    while(k)
    {
        if(k&1)a=cla(res,a);
        res=cla(res,res);
        k>>=1;
    }
    return a;
}
int main()
{
    int k;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)scanf("%lld",&f[i]);
        scanf("%d",&k);
        lenka res=POW(k);
        for(int i=0;i<n;i++)
        {
            d[i]=0;
            for(int k=0;k<n;k++)d[i]=(d[i]+res.a[k][i]*f[k])%MOD;
        }
        for(int i=0;i<n;i++)printf("%lld%c",d[i],i==n-1?'\n':' ');
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/mitsuha_/article/details/80685552