其实这题看一下数据范围就知道用O(n)的是绝对不行的,于是咱们换到log级的
再一看,运算形式还是快速取模的运算,那么就一定会在快速幂、矩阵快速幂、快速乘法中选择
显然,这题并没有涉及到快速幂
再一看,括号里有加法,于是很快的我们就可以确定这是矩阵快速幂
再一看数据范围,int64(long long)
推出矩阵后,我们会发现虽然我们都模m但是m的数据范围是不是也很大
那么我们考虑在做矩阵乘法的时候,乘法是不是也可能超出int64(long long)的范围,显然是有可能的
于是我们在做矩阵乘法的时候要用快速乘法协助一下
注意在运算的时候我们都是模m但是输出的结果还要模g
于是这题就A了
var
m,a,n,g :int64;
f1,f2 :array[0..2,0..2] of int64;
b,c :array[0..2] of int64;
function qp(a,b:int64):int64; //快速乘法
var
ans:int64;
begin
ans:=0;
while (b<>0) do
begin
if (b and 1=1) then ans:=(ans+a) mod m;
b:=b >>1;
a:=(a+a) mod m;
end;
exit(ans);
end;
procedure mul1;
var
j,k:longint;
begin
fillchar(c,sizeof(c),0);
for j:=1 to 2 do
for k:=1 to 2 do
c[j]:=(c[j]+qp(b[k] mod m,f1[k,j] mod m) mod m) mod m;
b:=c;
end;
procedure mul2;
var
i,j,k:longint;
begin
fillchar(f2,sizeof(f2),0);
for i:=1 to 2 do
for j:=1 to 2 do
for k:=1 to 2 do f2[i,j]:=(f2[i,j]+qp(f1[i,k] mod m,f1[k,j] mod m) mod m) mod m;
f1:=f2;
end;
begin
read(m,a,b[2],b[1],n,g);
f1[1,1]:=a;f1[1,2]:=0;f1[2,1]:=1;f1[2,2]:=1;
while (n>0) do //矩阵快速幂
begin
if (n mod 2<>0) then mul1;
n:=n div 2;
mul2;
end;
writeln(b[1] mod g);
end.
——by Eirlys
转载请注明出处=w=