hdu 1588 构造矩阵

来源:互联网 发布:ubuntu如何退出vim 编辑:程序博客网 时间:2024/05/28 22:13

这道题比较难

难在思维上,如果分块矩阵不知道怎么构造,这道题你是做不出来 的

如果 矩阵连乘模板不会,这道题你也是写不出来的;

现在请看一位大神的解题报告

http://blog.sina.com.cn/s/blog_626631420100vsug.html

备忘:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <stdio.h>
#define max1 4
#define max2 2
using namespace std;
long long k,b,n,m;
struct matrix1
{
 long long f[max1][max1];    
};
struct matrix2
{
 long long f[max2][max2];
};
matrix2 P2={0,1,
            1,1 
           };
matrix2 I2={1,0,
            0,1 
           };
matrix1 P1={0,0,1,0,
            0,0,0,1,
            0,0,1,0, 
            0,0,0,1
           };
matrix1 I1={1,0,0,0,
            0,1,0,0,
            0,0,1,0,
            0,0,0,1
           };
matrix2 mul2(matrix2 a,matrix2 b)
{
  matrix2 c;
  memset(c.f,0,sizeof(c.f));
  for(int i=0;i<max2;i++)
   for(int j=0;j<max2;j++)
    for(int k=0;k<max2;k++)
    {
      c.f[i][j]+=((a.f[i][k]%m)*(b.f[k][j]%m))%m;
      c.f[i][j]%=m;
    }
  return c;
}
matrix2 quick_mod2(int b)
{
 matrix2 s=I2,m=P2;
 while(b)
 {
   if(b&1)
   {
     s=mul2(s,m);
   }
   b=b/2;
   m=mul2(m,m);
 }
 return s;
}
matrix1 mul1(matrix1 a,matrix1 b)
{
  matrix1 c;
  memset(c.f,0,sizeof(c.f));
  for(int i=0;i<max1;i++)
   for(int j=0;j<max1;j++)
    for(int k=0;k<max1;k++)
    {
      c.f[i][j]+=((a.f[i][k]%m)*(b.f[k][j]%m))%m;
      c.f[i][j]%=m;       
    }
  return c;
}
matrix1 quick_mod1(int b)
{
 matrix1 s=I1,m=P1;
 while(b)
 {
   if(b&1)
   {
     s=mul1(s,m);
   }
   b=b/2;
   m=mul1(m,m);
 }
 return s;
}
int main()
{
 while(scanf("%lld%lld%lld%lld",&k,&b,&n,&m)!=EOF)
 {
   matrix2 Ab=quick_mod2(b);
   matrix2 Ak=quick_mod2(k);
   P1.f[0][0]=Ak.f[0][0];  P1.f[0][1]=Ak.f[0][1];
   P1.f[1][0]=Ak.f[1][0];  P1.f[1][1]=Ak.f[1][1]; 
   matrix1 temp=quick_mod1(n);
   long long sum=0;
    sum=(Ab.f[0][0]*temp.f[0][3])%m;
    sum+=(Ab.f[0][1]*temp.f[1][3])%m; 
    sum%=m;
   printf("%lld\n",sum);
 }
 return 0;   
}


0 0
原创粉丝点击