Problem Description
Professor Brute is not good at algorithm design. Once he was asked to solve a path finding problem. He worked on it for several days and finally came up with the following algorithm:
Any fool but Brute knows that the function “funny” will be called too many times. Brute wants to investigate the number of times the function will be called, but he is too lazy to do it.
Now your task is to calculate how many times the function “funny” will be called, for the given a, b and n. Because the answer may be too large, you should output the answer module by P.
Any fool but Brute knows that the function “funny” will be called too many times. Brute wants to investigate the number of times the function will be called, but he is too lazy to do it.
Now your task is to calculate how many times the function “funny” will be called, for the given a, b and n. Because the answer may be too large, you should output the answer module by P.
Input
There are multiple test cases. The first line of the input contains an integer T, meaning the number of the test cases.
For each test cases, there are four integers a, b, P and n in a single line.
You can assume that 1≤n≤1000000000, 1≤P≤1000000, 0≤a, b<1000000.
For each test cases, there are four integers a, b, P and n in a single line.
You can assume that 1≤n≤1000000000, 1≤P≤1000000, 0≤a, b<1000000.
Output
For each test case, output the answer with case number in a single line.
Sample Input
3 3 4 10 3 4 5 13 5 3 2 19 100
Sample Output
Case #1: 2 Case #2: 11 Case #3: 12
Source
Recommend
zhuweicong
昨天半夜突然被叫去做数论题,还好比较简单,在假设公式成立的条件下水过。
具体公式推导见这里,顺便膜拜下AC大神:http://hi.baidu.com/aekdycoin/blog/item/b6f1762565bb403fc8955908.html
公式很好推,a^F(n-3)*b^F(n-2)。
代码:
#include <stdio.h>
#define MAXN 1000002
typedef struct
{
long long m[2][2];
}Matrix;
int mod;
int a,b;
int phi[MAXN+5];
int fib[50];
void PHI()
{
int i,k;
for (i=2;i<MAXN;i++)
{
phi[i]=i;
}
for (i=2;i<MAXN;i++)
{
if (phi[i]!=i) continue;
k=1;
while(k*i<MAXN)
{
phi[i*k]=phi[i*k]/i*(i-1);
k++;
}
}
}
long long Fpow(long long t,int n)
{
long long ret=1;
while(n)
{
if (n&1) ret=(ret*t)%mod;
n>>=1;
t=(t*t)%mod;
}
return ret;
}
Matrix Mul(Matrix a,Matrix b,int p)
{
int i,j,k;
Matrix c;
for (i=0;i<2;i++)
{
for (j=0;j<2;j++)
{
c.m[i][j]=0;
for (k=0;k<2;k++)
{
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%p;
}
}
}
return c;
}
long long CountFib(int n,int p)
{
int i;
Matrix a,b;
a.m[0][0]=a.m[0][1]=a.m[1][0]=b.m[0][0]=1;
a.m[1][1]=b.m[1][0]=0;
while(n)
{
if (n&1) b=Mul(a,b,p);
a=Mul(a,a,p);
n>>=1;
}
return b.m[0][0];
}
long long Power(int t,int n)
{
int i;
int p=phi[mod];
fib[0]=fib[1]=1;
for (i=2;i<=n;i++)
{
fib[i]=fib[i-1]+fib[i-2];
if (fib[i]>=p) break;
}
if (i>n)
{
return Fpow(t,fib[n]);
}
int f=CountFib(n,p)+p;
return Fpow(t,f);
}
int main()
{
int i,j,cnt=1,T,n;
long long ans;
PHI();
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&a,&b,&mod,&n);
printf("Case #%d: ",cnt++);
if (n==1)
{
printf("%d\n",a%mod);
continue;
}
if (n==2)
{
printf("%d\n",b%mod);
continue;
}
if (a==0 || b==0)
{
printf("0\n");
continue;
}
if (mod==1)
{
printf("0\n");
continue;
}
ans=(Power(a,n-3)*Power(b,n-2))%mod;
printf("%I64d\n",ans);
}
return 0;
}
本文详细介绍了如何使用数论知识解决数论题,通过假设公式成立的条件下快速求解并给出代码实现。其中包括公式推导、算法优化及复杂度分析。
1059

被折叠的 条评论
为什么被折叠?



