SoEasy!
TimeLimit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K(Java/Others)
Total Submission(s): 1083 Accepted Submission(s):303
ProblemDescription
Asequence Snisdefined as:
Wherea, b, n, m are positive integers.┌x┐is the ceil of x. Forexample, ┌3.14┐=4. You are to calculate Sn.
You,a top coder, say: So easy!
Input
Thereare several test cases, each test case in one line contains fourpositive integers: a, b, n, m. Where 0< a, m < 215,(a-1)2<b < a2,0 < b, n < 231.Theinput will finish with the end of file.
Output
Foreach the case, output an integer Sn.
SampleInput
23 1 2013
23 2 2013
22 1 2013
SampleOutput
4
14
4
Source
Recommend
zhoujiaqi2010
给个链接,详细的解释
http://www.klogk.com/posts/hdu4565/
一个需要注意的地方是快速幂的过程中由于取余可能出现负数,要化为正数。
#include<stdio.h>
__int64 a[3][3];
void power(__int64 n,__int64 m)
{
__int64 ans[3][3],b[3][3],i,j,k;
for(i=1; i<=2; i++)
for(j=1; j<=2; j++)
b[i][j]=a[i][j];
n--;//这里不知道为什么要减一?????
while(n)
{
if(n&1)
{
for(i=1; i<=2; i++)
for(j=1; j<=2; j++)
{
ans[i][j]=a[i][j];
a[i][j]=0;
}
for(i=1; i<=2; i++)
for(j=1; j<=2; j++)
for(k=1; k<=2; k++)
a[i][j]=((a[i][j]+ans[i][k]*b[k][j])%m+m)%m;
}
for(i=1; i<=2; i++)
for(j=1; j<=2; j++)
{
ans[i][j]=b[i][j];
b[i][j]=0;
}
for(i=1; i<=2; i++)
for(j=1; j<=2; j++)
for(k=1; k<=2; k++)
b[i][j]=((b[i][j]+ans[i][k]*ans[k][j])%m+m)%m;
n=n/2;
}
}
int main()
{
__int64 c,d,n,m,c1,c0;
while(scanf("%I64d%I64d%I64d%I64d",&c,&d,&n,&m)!=EOF)
{
if(n==1)
{
printf("%I64d\n",2*c%m);
continue;
}
a[1][1]=2*c;
a[1][2]=d-c*c;
a[2][1]=1;
a[2][2]=0;
power(n-1,m);
c1=2*c;
c0=2;
printf("%I64d\n",((a[1][1]*c1+a[1][2]*c0)%m+m)%m);
}
return 0;
}
后面有详细的解释: