uva11582 斐波拉切数列循环节+欧拉定理降幂

来源:互联网 发布:数据统计的英文 编辑:程序博客网 时间:2024/05/17 02:33

The i’th Fibonacci number f(i) is
recursively defined in the following
way:
• f(0) = 0 and f(1) = 1
• f(i + 2) = f(i + 1) + f(i) for
every i ≥ 0
Your task is to compute some
values of this sequence.
Input
Input begins with an integer t ≤
10, 000, the number of test cases.
Each test case consists of three integers
a, b, n where 0 ≤ a, b < 2
64
(a and b will not both be zero) and
1 ≤ n ≤ 1000.
Output
For each test case, output a single line containing the remainder of f(a
b
) upon division by n.
Sample Input
3
1 1 2
2 3 1000
18446744073709551615 18446744073709551615 1000
Sample Output
1
21
250

题目意思:
给a,b,n三个数,求f(a^b)%n
a,b最大值2^64-1,用unsigned long long n=1000
思路:
打表找出每个n的循环节及其长度,降下幂(不降也行)。

#include<stdio.h>#include<algorithm>#include<iostream>#include<cmath>#include<cstring>#include<vector>#include<queue>using namespace std;#define ull unsigned long longconst int MAX_N=1005;int euler[MAX_N<<4];//注意这里要降幂的话求的是循环节长度的欧拉函数,大于1005void euler_init(){    int i,j;    euler[1]=1;    for(i=2;i<MAX_N<<4;i++)      euler[i]=i;    for(i=2;i<MAX_N<<4;i++)       if(euler[i]==i)          for(j=i;j<MAX_N<<4;j+=i)            euler[j]=euler[j]/i*(i-1);} int quickpowmod(ull x,ull y, int mod){      int ret = 1;      while(y){         if(y&1)             ret = ret*x%mod;         x = x*x%mod;         y >>= 1;     }     return ret; }int g[MAX_N];int f[MAX_N][MAX_N<<4];//循环节长度要大于1005,因为是两个相同(最差应该是MAX_N的平方,但开不了这么大)ull a,b;int T,ans,n;void get_gf(){//找到循环节    for(int i=2;i<MAX_N;i++){        f[i][0]=0;        f[i][1]=1;        for(int j=2;;j++){            f[i][j]=(f[i][j-1]+f[i][j-2])%i;            if(f[i][j-1]==0&&f[i][j]==1){                g[i]=j-1;                break;            }        }    }}int main(){    euler_init();    get_gf();    scanf("%d",&T);    while(T--){        scanf("%llu%llu%d",&a,&b,&n);        if(a==0||n==1)cout<<0<<endl;        else {        int a1=a%g[n];        int b1;        if(b<euler[g[n]])b1=b;//降下幂        else {        b1=b%euler[g[n]]+euler[g[n]];        }        ans=quickpowmod(a1,b1,g[n]);        cout<<f[n][ans]<<endl;    }    }    return 0;}
0 0
原创粉丝点击