HDU 3221Brute-force Algorithm(降冪公式 神似hdu4549)
Brute-force Algorithm
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1940 Accepted Submission(s): 475
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
題目大意:這個題目主要開始感覺意思難懂一點,實際上就是迭代的思想,f(1)=a, f(2)=b, f(3)=f(2,f(1))=f(1)*f(2)=a*b, f(4)=f(3,f(2))=f(3)*f(2)=a*b^2, f(5)=a^2*b^3.....後面的規律就一目瞭然了吧,然後給你一個地址。hdu4549M斐波那契數列題目真的是驚人的相似.
解題思路:只是兩者有一點不同,前面那個hdu4549直接%1e9+7,
而小費馬定理a^(p-1)%p==1,(a,p互質,且p為質數),很顯然p==1e9+7滿足這個條件,所以可以用小費馬定理降冪:a^t%p==a^(t%(p-1))。可以理解為p-1為一個迴圈節。 但是這個題目就不是這樣了,這也是兩點的不同之處!這個p可能不是質數,因此費馬小定理失效,但是可以用降冪公式:(A^x)%C=A^(x%phi(C)+phi(C))%C(x>=phi(C)).主要思想就是用矩陣的快速冪把a,b的指數算出來,注意算指數的時候結合降冪公式,然後最後直接用快速冪算出結果即可。
如果對矩陣的快速冪那一塊或者開始推出fibo數列這塊不清楚的,可以看HDU 4549M斐波那契數列(矩陣快速冪+費馬小定理)
AC程式碼:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
__int64 mo,phi;
__int64 ret[2][2],tmp[2][2],p[2][2];
__int64 n;
void init() //初始化
{
ret[0][0]=1; ret[0][1]=1;
ret[1][0]=1; ret[1][1]=0;
p[0][0]=1; p[0][1]=1;
p[1][0]=1; p[1][1]=0;
}
void cal1() //!(n&1)
{
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
tmp[i][j]=p[i][j];
p[i][j]=0;
}
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++)
{
p[i][j]=p[i][j]+tmp[i][k]*tmp[k][j];
if(p[i][j]>=phi)
p[i][j]=p[i][j]%phi+phi;
}
}
void cal2() //n&1
{
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
tmp[i][j]=ret[i][j];
ret[i][j]=0;
}
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++)
{
ret[i][j]=ret[i][j]+tmp[i][k]*p[k][j];
if(ret[i][j]>=phi)
ret[i][j]=ret[i][j]%phi+phi;
}
}
void fastmi() //矩陣的快速冪
{
init();
n-=3;
while(n)
{
if(n&1)
cal2();
cal1();
n>>=1;
}
}
__int64 pow(__int64 base,__int64 p) //快速冪
{
__int64 ans=1;
while(p)
{
if(p&1)
ans=(ans*base)%mo;
base=(base*base)%mo;
p>>=1;
}
return ans;
}
__int64 geteuler(__int64 n)
{
__int64 m=sqrt(n+0.5),ans=n,i;
for(i=2;i<=m;i++)
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0)
n/=i;
}
if(n>1)
ans=ans/n*(n-1);
return ans;
}
int main()
{
__int64 a,b;
int i,tes;
scanf("%d",&tes);
for(i=1;i<=tes;i++)
{
scanf("%I64d%I64d%I64d%I64d",&a,&b,&mo,&n);
n--;
phi=geteuler(mo); //得到尤拉值
__int64 ans1,ans2,res1,res2;
if(n==0) ans1=1,ans2=0;
else if(n==1) ans1=0,ans2=1;
else if(n==2) ans1=1,ans2=1;
else
{
fastmi();
ans2=(ret[0][0]+ret[0][1]); //b的次數
ans1=(ret[1][0]+ret[1][1]); //a的次數
}
//printf("%I64d %I64d\n",ans1,ans2);
if(ans1>=phi)
ans1=ans1%phi+phi;
if(ans2>=phi)
ans2=ans2%phi+phi;
res1=pow(a,ans1);
res2=pow(b,ans2);
__int64 res=(res1*res2)%mo;
printf("Case #%d: %I64d\n",i,res);
}
return 0;
}
//0MS
相關文章
- HDU3221Brute-force Algorithm(矩陣快速冪&&指數降冪)Go矩陣
- HDU 4686 (推公式+矩陣快速冪)公式矩陣
- HDU1792(公式)公式
- 冪的一個公式(一)公式
- 冪的一個公式(二)公式
- HDU 2685 I won't tell you this is about number theory (數論 公式 快速冪取模)公式
- HDU 1575 Tr A(矩陣快速冪)矩陣
- HDU 4565 So Easy!(矩陣快速冪)矩陣
- HDU 4965 Fast Matrix Calculation(矩陣快速冪)AST矩陣
- HDU 2157 How many ways?? (矩陣快速冪)矩陣
- HDU 1005 Number Sequence(矩陣快速冪)矩陣
- HDU 2256Problem of Precision(矩陣快速冪)矩陣
- HDU 1575 Tr A【矩陣快速冪取模】矩陣
- HDU 1005 Number Sequence:矩陣快速冪矩陣
- HDU5411CRB and Puzzle(矩陣快速冪)矩陣
- HDU 2276 - Kiki & Little Kiki 2 (矩陣快速冪)矩陣
- HDU 4291 A Short problem(矩陣快速冪+迴圈節)矩陣
- HDU 4565 So Easy!(公式化簡+矩陣)公式矩陣
- FZU1759Super A^B mod C(快速冪取模) 公式公式
- HDU-3461 Code Lock 並查集 + 二分求冪並查集
- 核化線性降維中部分公式的推導公式
- HDU4675 GCD of Sequence(預處理階乘逆元+推公式)GC公式
- HDU 4549 M斐波那契數列(矩陣快速冪+費馬小定理)矩陣
- HDU - 1061 Rightmost Digit(二分快速冪板題)Git
- algorithmGo
- HDU 4549M斐波那契數列(矩陣快速冪+費馬小定理)矩陣
- HDU 1299 Diophantus of Alexandria (公式變形 分解質因數)公式
- Kruskal algorithmGo
- 【HDU - 1792】A New Change Problem(推公式、互質數的最大不能表示數)公式
- Expectation Maximization AlgorithmGo
- Branch and Bound AlgorithmGo
- Introduction to AlgorithmGo
- Z-algorithmGo
- HDU 3117 Fibonacci Numbers(Fibonacci矩陣加速遞推+公式)矩陣公式
- 快速冪
- Algorithm assignment 1Go
- Algorithm in Javascript Bubble SortGoJavaScript
- Algorithm in Javascript Bucket SortGoJavaScript