(A1B1+A2B2+ ... +AHBH)mod M.
高次幂取模
乘方取模问题 计算x的值, a^n=x(mod(m))。
显然 a^n = a*(a^n-1(mod(m)))(mod(m)).
ans = 1;
for(int i = 0 ; i < n ; i++)
{
ans *= a;
ans %=m;
}
最简单的代码如上。
这个算法的时间复杂度是O(n),假如给的n很大,一定会超时的。
下面就介绍一种快速幂算法
对指数n进行二分,那么显然有
a^n%m = (a^n/2)^2%m (n为偶数) (a^n/2)^2%m*a%m (n为奇数)。
这样就把时间复杂度从O(n)降到了O(logn)了
代码如下,代码适合m不超过int 的范围
long long quick_mod(long long a,long long b,long long m) /*快速幂算法,类似二分的思想*/
{
long long ans = 1;
while(b)
{
if(b&1)
{
ans*=a;
ans%=m;
}
b>>=1LL;
a*=a;
a%=m;
}
return ans;
}
矩阵幂乘取模
要用到快速幂的思想。
唯一的区别就是整数乘法变成了矩阵乘法。
typedef struct
{
int m[Maxsize][Maxsize];
} Matrax;
Matrax multi(Matrax a,Matrax b) /*矩阵乘法*/
{
Matrax c;
for(int i = 0 ; i < n ; i++)
{
for(int j = 0 ; j < n ; j++)
{
c.m[i][j] = 0;
for(int k = 0 ; k < n ; k++)
{
c.m[i][j]+= a.m[i][k]*b.m[k][j];
}
c.m[i][j]%=M;
}
}
return c;
}
Matrax power(int k) /*矩阵快速幂*/
{
Matrax p,ans;
ans = per;
p = a;
while(k)
{
if(k&1)
{
ans = multi(ans,p);
}
k>>=1;
p = multi(p,p);
}
return ans;
}