hdu 5015

来源:互联网 发布:vm centos 桥接模式 编辑:程序博客网 时间:2024/06/03 09:15

神秘莫测的bug,一个是不知道怎么Wa的一个是不知道怎么A的。。。。。

喜欢重写代码也是有原因的嘛。

矩阵快速幂。比赛的时候想过,但是没有往矩阵方面想,现在觉得矩阵好神奇。有公式的计算,若是计算次数大,都应想到建立矩阵加速计算。

可以建立矩阵

1000011 10 00111001111000001然后右乘矩阵(列向量)(233,46,17,23,3)这样,随后一个3 是用来构成2333的。

#include <stdio.h>#include <string.h>#define ll __int64#define maxn 20struct node{    ll mat[maxn][maxn];};int n,m;ll mod;struct node mul(node a,node b){    int i,j,k;    node c;    for(i=0;i<=n+1;i++) for(j=0;j<=n+1;j++) c.mat[i][j]=0;    for(i=0;i<=n+1;i++)        for(j=0;j<=n+1;j++)        for(k=0;k<=n+1;k++)        if(a.mat[i][k]&&b.mat[k][j])        c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j]%mod)%mod;    return c;};struct node solve(node a){    int i,j,k;    node res;    for(i=0;i<=n+1;i++)        for(j=0;j<=n+1;j++)          if(i==j)res.mat[i][j]=1;          else res.mat[i][j]=0;    while(m)    {        if(m&1) res=mul(res,a);        m>>=1;        a=mul(a,a);    }    return res;}int main(){    mod=10000007;   // freopen("in.txt","r",stdin);   // freopen("out.txt","w",stdout);    while(scanf("%d%d",&n,&m)!=EOF)    {        int i,j,k;        ll a[maxn];        node b,c;        for(i=0;i<=n+1;i++) for(j=0;j<=n+1;j++) b.mat[i][j]=0;        ll sum=0;        a[0]=233;a[n+1]=3;        for(i=1;i<=n;i++) scanf("%I64d",&a[i]);        b.mat[0][0]=10;b.mat[0][n+1]=1;        for(i=1;i<=n;i++)            for(j=0;j<=i;j++)            b.mat[i][j]=1;        b.mat[n+1][n+1]=1;        c=solve(b);        for(j=0;j<=n+1;j++) sum+=c.mat[n][j]*a[j]%mod;        printf("%I64d\n",sum%mod);    }    return 0;}


0 0
原创粉丝点击