数论 之 3012 Fibnacci Numbers

http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3012

题意:f[1]=1,f[2]=2,f[n]=f[n-1]+f[n-2],定义:,求

这道题只有1s,很明显模拟的话单单指数部分的 S[ x ] 就O(n)超时了,更不用说求幂了。

而该 f[ x ] 为斐波那契数列,于是想到的是构造一个矩阵,利用矩阵来求 f[ x ] 和 S[ x ] 。

初始的构造方法是一个4*4的矩阵:

记为A[ n ]=T * B[ n-1 ],然后可以得到 A[ n ]=T^(x-2) * B[ 2 ]    ( 当 x>2 时 )

然后用矩阵快速幂的方法 求 M=T^(x-2) , 然后 s[ n ]= M[ 0 ][ 0 ]*s[ 2 ] + M[ 0 ][ 1 ] * f^2[ 2 ] + M[ 0 ][ 2 ] * f^2[ 1 ] + M[ 0 ][ 3 ] * f[ 1 ]*f[ 2 ]

然后用降幂公式   s [ x ] =  , 其中 ψ ( n )为欧拉函数值

降幂之后再用快速幂取模的方法 求 ans = ( a^s ) % n 求最终的答案。

不过不知道哪出问题了,一直在 WA 和 TL 中来回跑。

然后换了个构造方法,构造 2*2 的矩阵:

 A[ X ] = |  f[ x+1 ]   f[ x ]    |         |  1  1  | ^(x+1)

                 |    f[ x ]     f[ x-1 ] |    =  |  1   0 |

会发现 S[ x ] = F[ x+1 ] * F[ x ] -1

用快速幂 将 F[ x+1 ] 和 F[ x ] 求出  则可以得到 S[ x ] 时间复杂度为O( log n ) 

然后再用降幂公式和快速幂取模 求 ans 为最终答案

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<climits>
#include<sstream>
#define eps 1e-9
#define pi aocs(-1)
#define INF 0x3f3f3f3f
#define inf -INF
using namespace std;

const int maxn = 1e3 + 10;

typedef long long LL;

LL a,x,n,phi_n,F1,F2;

struct matrix{
  LL m[2][2];
}p,q;

LL phi(LL n){  // 欧拉函数  s=s%phi+phi 降幂
  LL res = n;
  for(int i = 2;i*i<=n;++ i){
    if(n%i==0){
        res = res - res/i;
        do{
            n/=i;
        }while(n%i == 0);
    }
  }
  if(n > 1) res = res - res/n;
  return res;
}

matrix multi(matrix a,matrix b,LL mod){
  matrix c;
  for(int i = 0;i < 2;++ i)
  for(int j = 0;j < 2;++ j){
    c.m[i][j] = 0;
    for(int k = 0;k < 2;++ k)
        c.m[i][j]+=a.m[i][k]*b.m[k][j];
    c.m[i][j]%=mod;
  }
  return c;
}

matrix quick_mod(matrix a,LL b,LL mod){
  matrix ans = p;
  while(b){
    if(b&1) ans = multi(ans,a,mod);
    b>>=1;
    a = multi(a,a,mod);
  }
  return ans;
}

LL quickpow_mod(LL a,LL b,LL mod){
  LL res = 1;
  while(b){
    if(b&1) res = (res*a)%mod;
    b>>=1;
    a = (a*a)%mod;
  }
  return res;
}

void init(){
  p.m[0][0] = p.m[1][1] = 1; p.m[1][0] = p.m[0][1] = 0;
  q.m[0][0] = q.m[0][1] = q.m[1][0] = 1;q.m[1][1] = 0;

}

int main(){
    matrix ans;
    init();
    while(cin>>a>>x>>n&&a+x+n){
        phi_n = phi(n);
        ans = quick_mod(q,x+1,phi_n);
        cout<<"aaa "<<ans.m[0][0]<<ans.m[0][1]<<endl;
        F1 = ((ans.m[0][0]*ans.m[0][1]-1)%phi_n + phi_n )%phi_n + phi_n;
        LL res = quickpow_mod(a,F1,n);
        cout<<res<<endl;
    }
	return 0;
}

  

时间: 2024-08-09 23:54:19

数论 之 3012 Fibnacci Numbers的相关文章

(数论)D - Beautiful Numbers

D - Beautiful Numbers Vitaly is a very weird man. He's got two favorite digits a and b. Vitaly calls a positive integer good, if the decimal representation of this integer only contains digits a and b. Vitaly calls a good number excellent, if the sum

codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)

In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 = 1; F2 = 1; Fn = Fn - 1 + Fn - 2 (n > 2). DZY loves Fibonacci numbers very much. Today DZY gives you an array consisting of n integers: a1, a2, ...,

hdoj 1492 The number of divisors(约数) about Humble Numbers 【数论】【质因子分解 求和】

定理:一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的个数就是,(r1+1)*(r2+1)*...*(rk+1). 理解:为什么是加1之后再相乘,因为一个数的的因子数至少为1和他自身,但因为r1,r2..可以为0,所以因子的个数为(r1+1)... 拓展一下: 定理1: 一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的

codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新

DZY Loves Fibonacci Numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-14) Description In mathematical terms, the sequence Fn of Fibonacci numbers is defi

uva 10539 - Almost Prime Numbers(数论)

题目链接:uva 10539 - Almost Prime Numbers 题目大意:给出范围low~high,问说在这个范围内有多少个数满足n=pb,(p为素数). 解题思路:首先处理出1e6以内的素数,然后对于每个范围,用solve(high)?solve(low?1),solve(n)用来处理小于n的满足要求的数的个数.枚举素数,判断即可. #include <cstdio> #include <cstring> typedef long long ll; const int

uva 1530 - Floating Point Numbers(数论)

题目链接:uva 1530 - Floating Point Numbers 题目大意:给出一个16位的二进制数,用来表示一个浮点数,第一位为符号,1~7位表示一个十进制的数s,e=63-s;剩下的8位为小数部分,默认整数部分为1,得到f,然后最后a=f*2^e,要求用科学计数法输出a. 解题思路:模拟就好了,注意0的情况特殊处理,以及科学计数法的整数部分不能为0. #include <cstdio> #include <cstring> #include <cmath>

POJ 1995 Raising Modulo Numbers (数论-整数快速幂)

Raising Modulo Numbers Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4379   Accepted: 2516 Description People are different. Some secretly read magazines full of interesting girls' pictures, others create an A-bomb in their cellar, oth

洛谷P2723 丑数 Humble Numbers [2017年 6月计划 数论07]

P2723 丑数 Humble Numbers 题目背景 对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S.这个正整数集合包括,p1.p1*p2.p1*p1.p1*p2*p3...(还有其 它).该集合被称为S集合的“丑数集合”.注意:我们认为1不是一个丑数. 题目描述 你的工作是对于输入的集合S去寻找“丑数集合”中的第N个“丑数”.所有答案可以用longint(32位整数)存储. 补充:丑数集合中每个数从小到大排列,每个丑

HDU1058 Humble Numbers 【数论】

Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17407    Accepted Submission(s): 7565 Problem Description A number whose only prime factors are 2,3,5 or 7 is called a humble numb