zoukankan      html  css  js  c++  java
  • luogu P1939 【模板】矩阵加速(数列)

    嘟嘟嘟

    没错,就是一个板子。

    够早的矩阵很简单:

    1 0 1

    1 0 0

    0 1 0

    然后我们把这个矩阵快速幂乘n - 3次后,a[0][0] + a[0][1] + a[0][2]就是答案。

    然而我刚开始一直把a[0][0] + a[0][2]当成答案,所以一直不对。因为递推式是这么给的,我就觉得n和n - 2没有关系。但是在矩阵上,n就应该等于转移矩阵的第一行乘以刚开始的矩阵(就是一列1 1 1)的第一列。

    这样就可以推断,如果快速幂乘n - 2次后,答案应该是a[1][0] + a[1][1] + a[1][2]。

    然而我没弄懂的是:乘n次后,答案为啥是a[1][0] ?

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 //const int maxn = ;
    21 const ll mod = 1e9 + 7;
    22 inline ll read()
    23 {
    24     ll ans = 0;
    25     char ch = getchar(), last = ' ';
    26     while(!isdigit(ch)) {last = ch; ch = getchar();}
    27     while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
    28     if(last == '-') ans = -ans;
    29     return ans;
    30 }
    31 inline void write(ll x)
    32 {
    33     if(x < 0) x = -x, putchar('-');
    34     if(x >= 10) write(x / 10);
    35     putchar(x % 10 + '0');
    36 }
    37 
    38 const int N = 3;
    39 struct Mat
    40 {
    41     ll a[N][N];
    42     Mat operator * (const Mat& oth)const
    43     {
    44         Mat ret; Mem(ret.a, 0);
    45         for(int i = 0; i < N; ++i)
    46             for(int j = 0; j < N; ++j)
    47                 for(int k = 0; k < N; ++k)
    48                     ret.a[i][j] += a[i][k] * oth.a[k][j], ret.a[i][j] %= mod;
    49         return ret;
    50     }
    51 }f;
    52 void init()
    53 {
    54     Mem(f.a, 0);
    55     f.a[0][0] = f.a[0][2] = 1;
    56     f.a[1][0] = f.a[2][1] = f.a[3][2] = 1;    
    57 }
    58 
    59 Mat quickpow(Mat A, ll b)
    60 {
    61     Mat ret; Mem(ret.a, 0);
    62     for(int i = 0; i < N; ++i) ret.a[i][i] = 1;
    63     for(; b; b >>= 1, A = A * A)
    64         if(b & 1) ret = ret * A;
    65     return ret;
    66 }
    67 
    68 int main()
    69 {
    70     
    71     int T = read();
    72     init();
    73     while(T--)
    74     {
    75         int n = read();
    76         if(n < 4) {puts("1"); continue;}
    77         n -= 3;
    78         Mat A = quickpow(f, n);
    79         write((A.a[0][0] + A.a[0][1] + A.a[0][2]) % mod), enter;
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    用GDB调试程序(一)
    ZOJ Problem Set
    android 去除标题
    【hadoop之翊】——基于CentOS的hadoop2.4.0伪分布安装配置
    layoutSubviews总结
    用数据说话,外贸产品选择(中篇)-google趋势分析法
    Apache介绍
    浅谈android4.0开发之GridLayout布局
    Android GridView 分页加载数据
    Android TableLayout中的使用说明
  • 原文地址:https://www.cnblogs.com/mrclr/p/9943281.html
Copyright © 2011-2022 走看看