• [51NOD1537] 分解(递推,矩阵快速幂)


    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1537

    思路:一开始用二项式拆了一下,发现这个式子的形式总能变成a+b*sqrt(2)的形式。然后就列了几个。

    1+1*sqrt(2)

    3+2*sqrt(2)

    7+5*sqrt(2)

    17+12*sqrt(2)

    挺明显的:ai=ai-1+2*bi-1,bi=ai-1+bi-1。

    转移的矩阵:

    1 2

    1 1

    起初我是怀疑这个题是有bug的,因为输出的结果要取模,但是我的代码是求出了未平方的值,但是这个时候如果平方溢出了呢?再取模会不会有问题?不过仔细一想,平方后对1e9+7取模结果一定小于它,所以它们的相对位置是统一的。推算出结果,判断一发a和b的顺序就行了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 const LL mod = (LL)1e9+7;
     6 const int maxn = 5;
     7 LL n;
     8 
     9 typedef struct Matrix {
    10   LL m[maxn][maxn];
    11   int r;
    12   int c;
    13   Matrix(){
    14     r = c = 0;
    15     memset(m, 0, sizeof(m));
    16   }
    17 } Matrix;
    18 
    19 Matrix mul(Matrix m1, Matrix m2) {
    20   Matrix ans = Matrix();
    21   ans.r = m1.r;
    22   ans.c = m2.c;
    23   for(int i = 1; i <= m1.r; i++) {
    24     for(int j = 1; j <= m2.r; j++) {
    25          for(int k = 1; k <= m2.c; k++) {
    26         if(m2.m[j][k] == 0) continue;
    27         ans.m[i][k] = ((ans.m[i][k] + m1.m[i][j] * m2.m[j][k] % mod) % mod) % mod;
    28       }
    29     }
    30   }
    31   return ans;
    32 }
    33 
    34 Matrix quickmul(Matrix m, LL n) {
    35   Matrix ans = Matrix();
    36   for(int i = 1; i <= m.r; i++) {
    37     ans.m[i][i]  = 1;
    38   }
    39   ans.r = m.r;
    40   ans.c = m.c;
    41   while(n) {
    42     if(n & 1) ans = mul(m, ans);
    43     m = mul(m, m);
    44     n >>= 1;
    45   }
    46   return ans;
    47 }
    48 
    49 int main() {
    50   //freopen("in", "r", stdin);
    51   while(~scanf("%lld", &n)) {
    52     Matrix p; p.c = 2; p.r = 2;
    53     p.m[1][1] = 1; p.m[1][2] = 2;
    54     p.m[2][1] = 1; p.m[2][2] = 1;
    55     Matrix q = quickmul(p, n);
    56     LL a = q.m[1][1], b = q.m[2][1];
    57     a = (a * a) % mod;
    58     b = (((b * b) % mod) * 2) % mod;
    59     if(a == b + 1) printf("%lld
    ", a);
    60     else if(a + 1 == b) printf("%lld
    ", b);
    61     else puts("no");
    62   }
    63   return 0;
    64 }
  • 相关阅读:
    替换iframe的内容
    富文本编辑器
    《将CSDN博客搬至博客园》
    学习mongoDB的一些感受(转自:http://blog.csdn.net/liusong0605/article/details/11581019)
    图片上传限制文件类型
    【文章阅读】事务和分布式事务学习理解
    【IDEA】IDEA使用教程+技巧
    【文章阅读】任务、消息队列、以及广播的理解
    进程、线程、协程理解
    动态代理:JDK原生动态代理(Java Proxy)和CGLIB动态代理原理+附静态态代理
  • 原文地址:https://www.cnblogs.com/kirai/p/5998301.html
Copyright © 2020-2023  润新知