SPOJ AMR10E Stocks Prediction

来源:互联网 发布:单片机编写卡尔曼滤波 编辑:程序博客网 时间:2024/05/16 16:06

http://www.spoj.pl/problems/AMR10E




矩阵快速幂 处理出一个向后移k位的矩阵,外加一个求和系数


#include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <map>using namespace std;long long x[9],a[9];#define MOD 1000000007 #define Maxe 100  struct Matrix{int m,n;long long date[Maxe][Maxe];Matrix(){n=m=0;memset(date,0,sizeof(date));}Matrix(int ne,int me):m(ne),n(me){ memset(date,0,sizeof(date));}Matrix operator * (const Matrix &a){Matrix ret(m,a.n);for (int i=0;i<m;i++)for (int j=0;j<a.n;j++)for (int k=0;k<a.m;k++)ret.date[i][j]=(ret.date[i][j]+(date[i][k]*a.date[k][j])%MOD)%MOD;return ret;}void set(){memset(date,0,sizeof(date));for (int i=0;i<=max(m,n);i++)date[i][i]=1;return ;}};Matrix pow_mod(Matrix a,int n){Matrix temp(a.m,a.n);temp.set();Matrix T=a;for (int i=n;i;i>>=1,T=T*T) if(i&1) temp=temp*T;return temp;}int main (){int r,k,n;//freopen("date.in","r",stdin);//freopen("date1.out","w",stdout);int T;scanf("%d",&T);while (T--){scanf("%d%d%d",&n,&r,&k);for (int i=0;i<r;i++){scanf("%lld",&x[i]);}for (int i=0;i<r;i++){scanf("%lld",&a[i]);}Matrix T(r+1,r+1);Matrix A(r+1,1);for (int i=0;i<r;i++){T.date[0][i]=a[i];}for (int i=1;i<r;i++){T.date[i][i-1]=1;}for (int i=0;i<=r;i++){T.date[r][i]=1;}for (int i=0;i<r;i++){A.date[i][0]=x[r-1-i];}int t=k;long long ans=0;while (t<r) t+=k;if(k<r){for(int i=1;i<r;i++){if((i%k)==0){ans+=x[i-1];}}}for (int i=r;i<t;i++){A=T*A;}T=pow_mod(T,k);ans+=A.date[0][0];A.date[r][0]=ans;for (int i=0;i<r;i++){T.date[r][i]=T.date[0][i];}T.date[r][r]=1;A=pow_mod(T,(n-(t/k)))*A;ans=A.date[r][0];printf("%lld\n",ans%MOD);}return 0;}


0 0
原创粉丝点击