UVA1386 快速矩阵幂 O(n²logk)

来源:互联网 发布:java异常中的finally 编辑:程序博客网 时间:2024/06/05 19:45

点击打开链接

友矩阵为循环矩阵,储存和计算矩阵乘法时只算出第一行

#pragma comment(linker, "/STACK:1024000000,1024000000")#include <stdio.h>#include <string.h>#include <iostream>#include <cctype>#include <string>#include <cmath>#include <algorithm>#include <queue>#include <set>#include <vector>#include <map>#define PR pair<int,int>#define MP make_pair#define fi first#define se second#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define sqr(x) ((x)*(x))#define ll long long#define ull unsigned __int64const ll INF = 1e18;const int inf=0x3f3f3f3f;const int M=444444;const int N=505;const int MOD=1000000007;const double eps=1e-10;const double pi=3.1415926536;using namespace std;int n,m,d,c;struct MAT{    ll mat[N];    friend MAT operator*(MAT &x,MAT &y);    friend MAT operator^(MAT x,int y);};typedef struct MAT Mat;Mat operator*(Mat &x,Mat &y){    Mat ans;    for(int j=0;j<n;j++)    {        ans.mat[j]=0;        for(int k=j,cnt=0;cnt<n;k=(k+1)%n,cnt++)        {            ans.mat[j]=(ans.mat[j]+y.mat[cnt]%m*x.mat[k]%m)%m;        }    }    return ans;}Mat operator^(Mat x,int y){    y--;    Mat init=x;    while(y)    {        if(y&1) init=init*x;        x=x*x;        y>>=1;    }    return init;}Mat a,b;int main(){    while(~scanf("%d%d%d%d",&n,&m,&d,&c))    {        for(int i=0;i<n;i++)            scanf("%lld",&a.mat[i]);        memset(b.mat,0,sizeof(b.mat));        for(int i=0;i<d+1;i++)            b.mat[i]=1;        for(int i=n-1;i>=n-d;i--)            b.mat[i]=1;        b=b^c;        for(int i=0;i<n;i++)        {            ll ans=0;            for(int j=(n-i)%n,cnt=0;cnt<n;j=(j+1)%n,cnt++)                ans+=a.mat[cnt]%m*b.mat[j]%m;            printf("%lld",ans%m);            if(i==n-1) puts("");            else printf(" ");        }    }}


0 0
原创粉丝点击