题目链接

luoguP4000 斐波那契数列

题解

根据这个东西

https://www.cnblogs.com/sssy/p/9418732.html

我们可以找出%p意义下的循环节

然后就可以做了

人傻,自带,大,常数

代码

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL maxn = 1000007;
LL dp[maxn * 10];
LL prime[maxn],s = 0;
bool vis[maxn];
void init_prime() {
for(LL i = 2;i < maxn;i ++) {
if(!vis[i]) prime[s ++] = i;
for(LL j = 0;j < s && i * prime[j] < maxn;j ++) {
vis[i * prime[j]] = 1;
if(i%prime[j] == 0) break;
}
}
}
LL pow_mod(LL a1,LL b1){
LL ret = 1;
for(;b1;b1 >>= 1,a1 *= a1)
if(b1 & 1) ret = ret * a1;
return ret;
}
LL pow_mod2(LL a,LL b,LL p) {
LL ret = 1;
for(;b;b >>= 1,a = a * a % p)
if(b & 1) ret = ret * a % p;
return ret;
}
LL gcd(LL a,LL b) { return b ? gcd(b,a % b) : a; }
bool f(LL n,LL p) {
if(pow_mod2(n,(p - 1) >> 1,p) != 1) return false;
return true;
}
struct matrix{
LL x1,x2,x3,x4;
};
matrix matrix_a,matrix_b;
matrix M2(matrix aa,matrix bb,LL mod){
matrix tmp;
tmp.x1 = (aa.x1 * bb.x1 % mod + aa.x2 * bb.x3 % mod) % mod;
tmp.x2 = (aa.x1 * bb.x2 % mod + aa.x2 * bb.x4 % mod) % mod;
tmp.x3 = (aa.x3 * bb.x1 % mod + aa.x4 * bb.x3 % mod) % mod;
tmp.x4 = (aa.x3 * bb.x2 % mod + aa.x4 * bb.x4 % mod) % mod;
return tmp;
}
matrix M(LL n,LL mod){
matrix a,b;
a=matrix_a;b=matrix_b;
for(;n;n >>= 1,a = M2(a,a,mod))
if(n & 1) b = M2(b,a,mod);
return b;
}
LL fac[100][2],l,x,fs[1000];
void dfs(LL count,LL step) {
if(step == l) {
fs[x ++] = count;
return ;
}
LL sum = 1;
for(LL i = 0;i < fac[step][1];++ i) {
sum *= fac[step][0];
dfs(count * sum,step + 1);
}
dfs(count,step + 1);
}
LL solve2(LL p){
if(p < 1e6 && dp[p]) return dp[p];
bool ok = f(5,p);//判断5是否为p的二次剩余
LL t;
if(ok) t = p - 1;
else t = 2 * p + 2;
l = 0;
for(LL i = 0;i < s;i ++){
if(prime[i] > t / prime[i]) break;
if(t % prime[i] == 0) {
LL count = 0;
fac[l][0] = prime[i];
while(t % prime[i] == 0) count ++ , t /= prime[i];
fac[l ++][1] = count;
}
}
if(t > 1) fac[l][0]=t, fac[l++][1]=1;
x = 0;
dfs(1 , 0); //求t的因子
sort(fs,fs + x);
for(LL i = 0;i < x;i ++) {
matrix m1 = M(fs[i],p);
if(m1.x1 == m1.x4 && m1.x1 == 1 && m1.x2 == m1.x3 && m1.x2 == 0) {
if(p < 1e6) dp[p] = fs[i];
return fs[i];
}
}
}
LL get_M(LL n){
LL ans = 1,cnt;
for(LL i = 0;i < s;i ++) {
if(prime[i] > n / prime[i]) break;
if(n % prime[i] == 0) {
LL count = 0;
while(n % prime[i] == 0) count ++,n /= prime[i];
cnt = pow_mod(prime[i],count - 1);
cnt *= solve2(prime[i]);
ans = (ans / gcd(ans , cnt)) * cnt;
}
}
if(n > 1){
cnt = 1;
cnt *= solve2(n);
ans = ans / gcd(ans,cnt) * cnt;
}
return ans;
}
char Ss[30000007];
struct bign {
int z[30000007],l;
void init() {
memset(z,0,sizeof(z));
scanf("%s",Ss + 1);
l = strlen(Ss + 1);
for(int i = 1;i <= l;i ++)
z[i] = Ss[l - i + 1] - '0';
}
LL operator % (const long long & a) const {
LL b = 0;
for (int i = l;i >= 1;i --)
b = (b * 10 + z[i]) % a;
return b;
}
}z;
LL m1;
struct Matrix {
LL a[3][3];
Matrix () { memset(a,0,sizeof a); }
Matrix operator * (const Matrix & p) const {
Matrix ret;
for(int i = 0;i <= 1;++ i)
for(int j = 0;j <= 1;++ j)
for(int k = 0;k <= 1;++ k)
ret.a[i][j] = (ret.a[i][j] + ( a[i][k] * p.a[k][j] ) % m1 ) % m1;
return ret;
}
};
LL solve(LL x) {
Matrix p,q;
p.a[0][0] = 1; p.a[0][1] = 1; p.a[1][0] = 1;
q.a[0][1] = 1;
for(;x;x >>= 1,p = p * p)
if(x & 1) q = q * p;
return q.a[0][0];
}
main() {
LL t,n;
init_prime();
matrix_a.x1 = matrix_a.x2 = matrix_a.x3 = 1;
matrix_a.x4 = 0;
matrix_b.x1 = matrix_b.x4 = 1;
matrix_b.x2 = matrix_b.x3 = 0;
dp[2] = 3;dp[3] = 8;dp[5] = 20;
z.init(); scanf("%lld",&n); m1 = n;
n = get_M(n);
//printf("%lld\n",n % m1);
n = z % n;
printf("%lld\n",solve(n));
return 0;
}

luoguP4000 斐波那契数列的更多相关文章

  1. C#求斐波那契数列第30项的值(递归和非递归)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...

  3. js中的斐波那契数列法

    //斐波那契数列:1,2,3,5,8,13…… //从第3个起的第n个等于前两个之和 //解法1: var n1 = 1,n2 = 2; for(var i=3;i<101;i++){ var ...

  4. 剑指Offer面试题:8.斐波那契数列

    一.题目:斐波那契数列 题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项.斐波那契数列的定义如下: 二.效率很低的解法 很多C/C++/C#/Java语言教科书在讲述递归函数的时 ...

  5. 算法: 斐波那契数列C/C++实现

    斐波那契数列: 1,1,2,3,5,8,13,21,34,....     //求斐波那契数列第n项的值 //1,1,2,3,5,8,13,21,34... //1.递归: //缺点:当n过大时,递归 ...

  6. 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]

    P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...

  7. Python递归及斐波那契数列

    递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可 ...

  8. 简单Java算法程序实现!斐波那契数列函数~

    java编程基础--斐波那契数列 问题描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 思路:可能出现的情况:(1) n=1 ,一种方法 ;(2)n=2 ...

  9. js 斐波那契数列(兔子问题)

    对于JS初学者来说,斐波那契数列一直是个头疼的问题,总是理不清思路. 希望看完这篇文章之后会对你有帮助. 什么是斐波那契数列 : 答: 斐波那契数列,又称黄金分割数列.因数学家列昂纳多·斐波那契(Le ...

随机推荐

  1. OpenStack 计算服务 Nova介绍和控制节点部署(七)

    介绍 Nova是openstack最早的两块模块之一,另一个是对象存储swift.在openstack体系中一个叫做计算节点,一个叫做控制节点.这个主要和nova相关,我们把安装为计算节点nova-c ...

  2. CM记录-HDFS清理垃圾回收站

    HDFS数据块所在存储的目录满了的解决方法 1.增加磁盘空间 2.删除回收站 hadoop dfs -du -h 查看各个HDFS空间占用情况 hadoop dfs  -expunge  清空回收站 ...

  3. SpringBoot 读取配置文件及profiles切换配置文件

    读取核心配置文件 核心配置文件是指在resources根目录下的application.properties或application.yml配置文件,读取这两个配置文件的方法有两种,都比较简单. 先创 ...

  4. A Brief Overview of Deep Learning

    A Brief Overview of Deep Learning (This is a guest post by Ilya Sutskever on the intuition behind de ...

  5. html5 canvas用图案填充形状

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 浏览器存储:cookie

    Cookie是什么:cookie是指存储在用户本地终端上的数据,同时它是与具体的web页面或者站点相关的.Cookie数据会自动在web浏览器和web服务器之间传输,也就是说HTTP请求发送时,会把保 ...

  7. 第11月第18天 RACSequence

    1. RACSequence的内部存储结构就像一个单链表,有两个指针head和tail,head指针指向了当前链表的第一个元素,tail指向head指针下一个元素:根据RACSequence是否还有内 ...

  8. HDU 6395 Sequence 杜教板子题

    题目意思非常明确,就是叫你求第n项,据我们学校一个大佬说他推出了矩阵,但是我是菜鸡,那么肯定是用简单的方法水过啦!我们先p^(1/2)的复杂度处理出i=[i,p]范围内的所有种类的(int)(p/i) ...

  9. 【ARTS】01_05_左耳听风-20181210~1216

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  10. 【API】文件操作编程基础-CreateFile、WriteFile、SetFilePointer

    1.说明 很多黑客工具的实现是通过对文件进行读写操作的,而文件读写操作实质也是对API函数的调用. 2.相关函数 CreateFile : 创建或打开文件或I/O设备.最常用的I/O设备如下:文件,文 ...