hdu1757 A Simple Math Problem

来源:互联网 发布:电子软件是什么专业 编辑:程序博客网 时间:2024/05/23 19:56
 题目自己找吧,不贴了
思路:构造如下矩阵
a0a1a2a3a4a5a6a7a8a9 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 f(x-1) f(x-2) f(x-3)  f(x-4)    f(x-5) f(x-6)   f(x-7) f(x-8)   f(x-9) f(x-10)  


当以上两个矩阵相乘后会得到一个新矩阵

 f(x)f(x-1)     f(x-2)f(x-3)   f(x-4)f(x-5)   f(x-6)f(x-7)   f(x-8)f(x-9)  
如此这般,你只需要把第一个表格自乘(x-9)次,再与f(9)~f(0)相乘即可

代码:
#include <fstream>#include <cstring>#include <cstdio>#include <algorithm>#include <iostream>#include <vector>#include <cmath>#define MAX 11  //修改矩阵大小上限using namespace std;int x,k,M;//n为矩阵大小,k为幂,M为模long long sum;bool flag;struct node{    int kk[MAX][MAX];}unit,a;void init(){    //初始化矩阵    for(int i=1;i<MAX;i++)        for(int j=1;j<MAX;j++)        {            unit.kk[i][j]=(i==j);            a.kk[i][j]=0;        }}node mul(node aa,node bb){    node cc;    for(int i=1;i<MAX;i++)        for(int j=1;j<MAX;j++)        {            cc.kk[i][j]=0;            for(int p=1;p<MAX;p++)                cc.kk[i][j]=(cc.kk[i][j] + (aa.kk[i][p]*bb.kk[p][j])%M)%M;        }    return cc;}node pow(node aa,int exp){    node p=aa;    node q=unit;    while(exp)    {        if(exp&1)            q=mul(q,p);        exp/=2;        p=mul(p,p);    }    return q;}void cal(){    node ans=pow(a,x-9);    sum=0;    for(int i=1,j=9;i<=10;i++,j--)    {        sum=(sum+ans.kk[1][i]*j)%M;    }    printf("%lld\n",sum);}int main(){    init();    while(~scanf("%d%d",&x,&M))    {        for(int i=1;i<=10;i++)            scanf("%d",&a.kk[1][i]);        for(int i=2;i<=10;i++)            a.kk[i][i-1]=1;        cal();    }    return 0;}





原创粉丝点击