今天来讲的是在欧拉工程上的一道递推题,题目描述如下链接。

题目:https://projecteuler.net/problem=492

当然,这道题在51Nod上有一个比较通用的版本,链接如下

题目:http://www.51nod.com/contest/problem.html#!problemId=1361

题意:给定,并且有,给定两个数,求的值。其中

满足,并且为素数。

分析:首先对原递推式进行变换得到

       

那么令,继而有,而。到了这里,假设

那么我们带入继续递推会发现一个神奇的结论

其中假设取其中一个解如下

那么得到如下

好了,到了这里,最直观的做法就是根据上述公式求出,然后会带回去求出即可。

如果想用二次剩余的方法来做,因为可能无解,所以不能用这种方法做。看成更一般

形式的求解,比如下面

那么回忆之前的一篇文章:http://blog.csdn.net/acdreamers/article/details/8994222,重

点是HDU4565题,这是明显可以构造矩阵的,具体如何构造不再赘述。然后先得到递推式如下

所以最终得到如下

可以看到矩阵的指数很大,所以需要降小,而这是一个经典的矩阵找寻环节问题。之前有篇文章,如下

     链接:http://blog.csdn.net/acdreamers/article/details/25616461

当时那道题由于要求最小的循环节,所以要求比较精确,必须枚举因子。但是对于本题不同,我们只要能

求出一个合理的循环节即可,不要求最小的,因为不影响最终结果。

参照当时的结论,由于117不是素数,所以只有两种情况。

(1)如果117是的二次剩余时,最小循环节是的因子,我们可以取作为循环节。

(2)如果117是的二次非剩余时,最小循环节是的因子,可以取

为循环节。

到了这里大部分问题都已经解决。实际上当117是的二次非剩余时,循环节可以为,至于为什么是

正确的,请来个大神证明! 另外为2或者3时,需要特判。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>using namespace std;
typedef long long LL;const int N = 2;struct Matrix
{LL m[N][N];
};Matrix I =
{1, 0,0, 1
};LL quick_mod(LL a, LL b, LL m)
{LL ans = 1;a %= m;while(b){if(b & 1){ans = ans * a % m;b--;}b >>= 1;a = a * a % m;}return ans;
}LL Legendre(LL a, LL p)
{  LL t = quick_mod(a, (p - 1) >> 1, p);  if(t == 1) return 1;  return -1;
}  Matrix multi(Matrix a, Matrix b, LL m)
{Matrix c;for(int i = 0; i < N; i++){for(int j = 0; j < N; j++){c.m[i][j] = 0;for(int k = 0; k < N; k++)c.m[i][j] += a.m[i][k] * b.m[k][j] % m;c.m[i][j] %= m;}}return c;
}Matrix power(Matrix A, LL k, LL m)
{Matrix ans = I, p = A;while(k){if(k & 1){ans = multi(ans, p, m);k--;}k >>= 1;p = multi(p, p, m);}return ans;
}LL GetLoop(LL p)
{if(Legendre(117, p) == -1)return p + 1;return p - 1;
}int main()
{int T;scanf("%d", &T);while(T--){LL n, p;scanf("%lld %lld", &n, &p);if(p == 2 || p == 3){puts("1");continue;}Matrix A;A.m[0][0] = 11 % p;A.m[0][1] = p - 1;A.m[1][0] = 1;A.m[1][1] = 0;LL loop = GetLoop(p);LL x = quick_mod(2, n - 1, loop);x = ((x - 1) % loop + loop) % loop;Matrix ans = power(A, x, p);LL res = (ans.m[1][0] * 119 % p + ans.m[1][1] * 11 % p) % p;res = ((res - 5) % p + p) % p;res = res * quick_mod(6, p - 2, p) % p;printf("%lld\n", res);}return 0;
}

关于欧拉工程的一道递推题相关推荐

  1. HDU - 2044一只小蜜蜂 一道递推题

    一只小蜜蜂 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> ...

  2. 停不下来的团长奥尔加(一道递推题,思维很好啊....)

    停不下来的团长奥尔加 [题目描述] 奥尔加在一个长度为n+1的街道上跑着,初始,奥尔加在位置1上,他想要跑到 位置n+1去保护团员ride on. 空旷的大路上难免会有暗杀者,当奥尔加走到位置i时,会 ...

  3. 欧拉工程第12题 第一个拥有超过500个约数的三角形数是多少

    题目 三角形数序列是由对自然数的连加构造而成的.所以第七个三角形数是1+2+3+4+5+6+7=281+2+3+4+5+6+7=28. 那么三角形数序列中的前十个是: 1,3,6,10,15,21,2 ...

  4. 欧拉函数的一道练习题(附加容斥做法)

    jzd同学今天告诉了我们一道关于欧拉函数的题,一开始觉得毫无头绪,当身旁的erge同学切完开始装(xiao)逼(zhang)的时候,他无意间透露的欧拉函数四个字启发了我,最近做了一道很相似的题HDU1 ...

  5. gcd + 扩展欧几里得定理+递推乘法逆元(模板)

    gcd: int gcd(int a, int b){ return b==0? a: gcd(b, a%b); } 扩张欧几里得定理: 扩展欧几里德算法是用来在已知a, b求解一组x,y使得ax+b ...

  6. 斐波拉契数列的递推递归求解算法

    介绍: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数 ...

  7. 斐波拉契数列C++--递推

    [问题描述] 有斐波拉契数列1,1,2,3,5,8,13--,请按每行m个数据输出该裴波拉契数列的前n项,其中m,n从键盘输入 [输入形式] m为1-7之间的整数,n值是1-50之间的任意一整数. [ ...

  8. 欧拉工程第57题:Square root convergents

    题目链接 Java程序 package projecteuler51to60;import java.math.BigInteger; import java.util.Iterator; impor ...

  9. 我的欧拉工程之路_3

    Largest prime factor Problem 3 The prime factors of 13195 are 5, 7, 13 and 29. What is the largest p ...

最新文章

  1. java中xxe漏洞修复方法
  2. task一个任务结束后执行另一个操作
  3. c语言操作目录,c语言文件操作整理
  4. 使用的 SQL Server 版本不支持数据类型“datetime2”解决办法
  5. SAPGUI里实现自定义的语法检查
  6. linux禁止root用户直接登录sshd并修改默认端口
  7. c语言限制字符数,C语言中“不受限制”的字符串函数总结.pdf
  8. ECCV 2020 | 超快的车道线检测
  9. Kafka常用命令之kafka-console-consumer.sh
  10. java 解析数据包_一种基于Java语言的网络通讯数据包解析方法与流程
  11. python智能化推荐_windows python flask
  12. Android之Input子系统事件分发流程
  13. 20200210_logistic回归来预测违约的概率
  14. 测试工程师必备Linux知识点
  15. 在Windows系统上安装zookeeper
  16. CTF之Bugku 秋名山老司机
  17. android好用拍照框架,Github挺好用的android图片选择框架(拍照+从相册)
  18. 访问对象存储资源下载变成预览
  19. Windows10打开“运行”窗口
  20. JavaScript实现注册页面的表单验证

热门文章

  1. MyBatis 缓存详解-一级缓存(本地缓存)介绍
  2. 数据库问题解决后,应用面对的挑战
  3. 使用注解配置声明式事务控制
  4. Bean标签范围配置
  5. 制作模块-制作模块压缩包
  6. 物理设计-数据类型的选择
  7. 如何联网获取北京时间
  8. Linux tar vi gcc 指令
  9. Cortex-M3-建立向量表
  10. Cortex‐M3-总线接口