UVA - 10518 How Many Calls? (构造矩阵,快速幂)

题目链接

题意:

求f[n] = f[n-1] + f[n-2] + 1,在b(10000)进制下的最后一位数字的十进制表示。

思路:

构造矩阵即可,M矩阵是一个3_3的矩阵,M1矩阵是一个3_1的矩阵。。很easy,就不说了。

写题解的目的是,对于这种要求b进制下,最后一位或者最后两位的数字的十进制表示的问题,其实就是在说,取模的数是base或者base^2

1A美滋滋

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2017年10月01日 星期日 18时39分17秒
  4File Name :10518.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define PB push_back
 20#define fst first
 21#define sec second
 22#define lson l,m,rt<<1
 23#define rson m+1,r,rt<<1|1
 24#define ms(a,x) memset(a,x,sizeof(a))
 25typedef long long LL;
 26#define pi pair < int ,int >
 27#define MP make_pair
 28
 29using namespace std;
 30const double eps = 1E-8;
 31const int dx4[4]={1,0,0,-1};
 32const int dy4[4]={0,-1,1,0};
 33const int inf = 0x3f3f3f3f;
 34const int N = 5;
 35LL n,base;
 36struct Mat
 37{
 38    LL mat[N][N];
 39    void clear()
 40    {
 41    ms(mat,0);
 42    }
 43}M,M1;
 44Mat operator * ( Mat a,Mat b)
 45{
 46    Mat c;
 47    c.clear();
 48    for ( int i = 0  ;  i <  3 ; i++)
 49    for ( int j = 0 ; j < 3 ; j++)
 50        for  ( int k = 0 ;  k <  3 ; k++)
 51        c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]% base)se;
 52
 53    return c;
 54}
 55
 56Mat operator ^ (Mat a,LL b)
 57{
 58    Mat ret;
 59    ret.clear();
 60    for ( int i = 0 ; i < 3 ; i++) ret.mat[i][i] = 1;
 61    while (b>0)
 62    {
 63    if (b&1) ret = ret * a;
 64    b = b >> 1LL;
 65    a = a * a;
 66    }
 67    return ret;
 68}
 69LL solve()
 70{
 71    if (n==0) return 0;
 72    if (n==1) return 1;
 73    M.clear();
 74    M1.clear();
 75    M.mat[0][0] = M.mat[0][1] = M.mat[0][2] = 1;
 76    M.mat[1][0] = M.mat[2][2] = 1;
 77    M1.mat[0][0]=M1.mat[1][0]=M1.mat[2][0] = 1;
 78
 79    Mat ans;
 80    ans.clear();
 81    ans = (M ^ (n-1))*M1;
 82    return ans.mat[0][0]se;
 83}
 84
 85int main()
 86{
 87    #ifndef  ONLINE_JUDGE 
 88    freopen("./in.txt","r",stdin);
 89  #endif
 90    int cas = 0 ;
 91    while (~scanf("%lld %lld",&n,&base))
 92    {
 93        if (n==0&&base==0) break;
 94        LL ans = solve();
 95        printf("Case %d: %lld %lld %lld\n",++cas,n,base,ans);
 96    }
 97
 98
 99  #ifndef ONLINE_JUDGE  
100  fclose(stdin);
101  #endif
102    return 0;
103}