您的位置:首页 > 其它

Colossal Fibonacci Numbers! 巨大的斐波那契数 UVA - 11582

2017-06-26 14:58 288 查看
给你a b n,然后让你计算f(a^b)%n的值

这个题做了蛮久。首先是对这么大的数不知所措。计算f(a^b)%n,首先a^b,就已经很大了好吧,其中0<=a,b<2e64,都超过long long 的范围了。

然后参考了下dalao 们的博客,这个主要是发现斐波那契数列模上一个数之后,是会出现循环的。因为f[i]是由f[i-1],f[i-2]推出来的,如果f[i-1]和f[i-2]出现过了,即出现了循环。因为 模上n,一共有n种余数,然后f[i-1],f[i-2]连续两个数出现相同的话,一共不超过n^2;

a,b用什么存呢?法一:用unsighed long long ,范围刚好合适。法二用大数

如果不加if(a==0||n==1) printf(“0\n”);会RE,因为当n=1的时候,f[i]都是0.根本找不到两个1。

开始的想法是,我先预处理一个斐波那契的表,先模上1000,因为最大n的是1000,然后对于具体的值,我就直接模上具体的值。但是这样是有问题的。因为如果给你的数是1005,这个模1000是5,然后模3是二。但是1005直接模3 是0.。

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>

using namespace std;
const int maxn = 1e6+10;
int f[maxn];
#define inf 10000
int main()
{
int t;

4000
scanf("%d",&t);
while(t--)
{
unsigned long long a,b;
int n;
scanf("%llu %llu %d",&a,&b,&n);
int flag=0,time;
if(a==0||n==1) {printf("0\n");continue;}
f[0]=0;f[1]=f[2]=1;
for(int i=3;i<maxn;i++)
{
f[i]=(f[i-1]+f[i-2])%n;
if(f[i]%n==1&&f[i-1]%n==1) {time=i-2;break;}
}
unsigned long long temp=b,q=a%time,ans=1;
while(temp)
{
if(temp&1) ans=(ans*q%time)%time;
q=(q*q)%time;
temp=temp/2;
}
if(ans==0) ans=time;
printf("%d\n",f[ans]%n);
}
return 0;
}


大数

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>

using namespace std;
const int maxn = 1e6+10;
int f[maxn];
char a[100],b[100];
#define inf 10000
long long mo(char c[],int time)
{
int len=strlen(c);
long long ans=0;
for(int i=0;i<len;i++)
{
ans=((ans*10)+c[i]-'0')%time;
}
return ans;
}
long long chu(char c[],int shu)
{
int len=strlen(c);
long long ans=0,ys=0;
for(int i=0;i<len;i++)
{
ans=ans*10+(ys*10+c[i]-'0')/shu;
ys=(ys*10+c[i]-'0')%shu;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%s %s %d",a,b,&n);
int flag=0,time;
if(a[0]=='0'||n==1) {
printf("0\n");
continue;
}
f[0]=0;f[1]=f[2]=1;
for(int i=3;i<maxn;i++)
{
f[i]=(f[i-1]+f[i-2])%n;
if(f[i]==f[i-1]&&f[i]==1)
{
time=i-2;
break;
}
}
long long ans=0;
long long q=mo(a,time);
int blen=strlen(b);
if((b[blen-1]-'0')%2==0) ans=1;
else ans=q;
q=(q*q)%time;
long long temp=chu(b,2);
while(temp)
{
if(temp&1) ans=(ans*q%time)%time;
q=(q*q)%time;
temp=temp/2;
}
if(ans==0) ans=time;
printf("%d\n",f[ans]%n);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: