• 【HDU4990】递推式


    题目大意:给定序列 1, 2, 5, 10, 21, 42, 85, 170, 341 …… 求第n项 模 m的结果

    递推式 f[i]  = f[i - 2] + 2 ^ (i - 1);

    方法一: 构造矩阵, 求递推式

    方法二: 直接推公式,递推式求和,得到 f[n] = [2 ^ (n + 1) - 1] / 3 奇数, f[n] = [2 ^ (n + 1) - 2] / 3 偶数; 其实还可以进一步化简, 注意到 2 ^ 2k % 3 = 1, 2 ^ (2k + 1) % 3 = 2,于是 f[n] = 2 ^ (n + 1) / 3 ;于是答案就是 2 ^ (n + 1) % 3m / 3 (巧妙)

    源码(矩阵):

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #define mem0(a) memset(a, 0, sizeof(a))
     7 #define LL __int64
     8 using namespace std;
     9 struct Node{
    10     LL a[2][2];
    11 };
    12 Node multi(Node a, Node b, int m)
    13 {
    14     Node ans;
    15     mem0(ans.a);
    16     for(int i = 0; i < 2; i++) {
    17         for(int j = 0; j < 2; j++) {
    18             for(int k = 0; k < 2; k++) {
    19                 ans.a[i][j] += (a.a[i][k] * b.a[k][j]) % m;
    20             }
    21         }
    22     }
    23     return ans;
    24 }
    25 Node calc(Node a, int b, int m)
    26 {
    27     if(b == 1) return a;
    28     Node tmp = calc(a, b >> 1, m);
    29     int t = b & 1;
    30     tmp = multi(tmp, tmp, m);
    31     if(t) tmp = multi(tmp, a, m);
    32     return tmp;
    33 }
    34 Node a0;
    35 int main()
    36 {
    37     //freopen("in.txt", "r", stdin);
    38     int n, m;
    39     a0.a[0][0] = a0.a[1][0] = 1;
    40     a0.a[0][1] = 0;
    41     a0.a[1][1] = 4;
    42     while(~scanf("%d%d", &n, &m)) {
    43         LL ans = 0;
    44         if(n == 1) {
    45             cout<< 1 % m<< endl;
    46             continue;
    47         }
    48         if(n == 2) {
    49             cout<< 2 % m<< endl;
    50             continue;
    51         }
    52         if(n & 1) {
    53             Node one = calc(a0, (n - 1) >> 1, m);
    54             ans = (one.a[0][0] + one.a[1][0] * 4) % m;
    55         }
    56         else {
    57             Node one = calc(a0, (n - 2) >> 1, m);
    58             ans = (one.a[0][0] * 2 + one.a[1][0] * 8) % m;
    59         }
    60         cout<< ans<< endl;
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    Linux DNS配置
    SqlCommandBuilder 为SqlDataAdapter 提供 update、insert、delete 命令(自己利用select命令自动从数据库元数据推断)
    Dev中GridView——事件
    select 动态赋值 layui重新渲染
    url-loader和file-loader的区别和使用
    Fetch API
    Fetch API
    FormData上传文件
    Buffer、ArrayBuffer互转
    if exists用法(判断对象的用法)
  • 原文地址:https://www.cnblogs.com/jklongint/p/3961579.html
Copyright © 2020-2023  润新知