快速幂模板【快速幂+矩阵快速幂】

快速幂模板:

引入:就是将幂以二进制数分解,比如5的6次方,6被分解为2,4,即110,110&1为0,不执行ans=ans*a%mod,但是a=a*a每循环一次就执行一次,现在a=5*5,下一次循环11&1==1,执行ans=1*25,a=25*25;1&1==1,执行ans=25*a(也就是25*25),a=a*a(a有点大了,懒得写数字),你只看ans,你就会发现ans=25*25*25,就是5^2*5^4;这样子只要循环3次,而如果按照正常做法需要6次循环,如果更大,大家应该知道快速幂还是很快的。

如果当前的指数是偶数,我们把指数拆成两半,得到两个相同的数,然后把这两个相同的数相乘,可以得到原来的数;
如果当前的指数是奇数,我们把指数拆成两半,得到两个相同的数,此时还剩余一个底数,把这两个相同的数和剩余的底数这三个数相乘,可以得到原来的数。(5^6)=(5^3)*5*(5^2)

typedef long long ll;
int mod=1e9+7;
ll quick_pow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;	
	} 
	return ans%mod;
}

模板使用:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int mod=1e9+7;
ll quick_pow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;	
	} 
	return ans%mod;
}
int main(void)
{
	int a,b;
	while(~scanf("%d%d",&a,&b))
	{
		cout<<quick_sort(a,b)<<endl;
	}
	return 0;
}

矩阵快速幂模板:

const int maxn=2;
const int mod=10000;
struct Matrix{
	int a[maxn][maxn];
	void init()
	{
		memset(a,0,sizeof a);
		for(int i=0;i<maxn;i++)//单位矩阵 
		a[i][i]=1;
	}
};

//矩阵乘法 
Matrix mul(Matrix a,Matrix b)
{
	Matrix ans;
	for(int i=0;i<maxn;i++)
	{
		for(int j=0;j<maxn;j++)
		{
			ans.a[i][j]=0;
			for(int k=0;k<maxn;k++)
			{
				ans.a[i][j]+=a.a[i][k]*b.a[k][j];
				ans.a[i][j]%=mod;
			}
		}
	}
	return ans;
}

//矩阵快速幂
Matrix quick_pow(Matrix a,int n)
{
	Matrix ans;
	ans.init();
	while(n)
	{
		if(n&1) ans=mul(ans,a);
		a=mul(a,a);
		n>>=1;
	}
	return ans;
}

HDU模板题:

Tr A

Problem Description

A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。

Input

数据的第一行是一个T,表示有T组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。

Output

对应每组数据,输出Tr(A^k)%9973。

Sample Input

2 2 2 1 0 0 1 3 99999999 1 2 3 4 5 6 7 8 9

Sample Output

2 2686

#include<bits/stdc++.h>
using namespace std;
const int maxn=11;
const int mod=9973;
struct Matrix{
    int a[maxn][maxn];
    void init()
    {
        memset(a,0,sizeof a);
        for(int i=0;i<maxn;i++)//单位矩阵 
        a[i][i]=1;
    }
}init;

//矩阵乘法 
Matrix mul(Matrix a,Matrix b)
{
    Matrix ans;
    for(int i=0;i<maxn;i++)
    {
        for(int j=0;j<maxn;j++)
        {
            ans.a[i][j]=0;
            for(int k=0;k<maxn;k++)
            {
                ans.a[i][j]+=a.a[i][k]*b.a[k][j];
                ans.a[i][j]%=mod;
            }
        }
    }
    return ans;
}

Matrix quick_pow(Matrix a,int n)
{
    Matrix ans;
    ans.init();
    while(n)
    {
        if(n&1) ans=mul(ans,a);
        a=mul(a,a);
        n>>=1;
    }
    return ans;
}
int main(){
     int t,n,k;
    scanf("%d",&t);
    while(t--)
    {
        
        scanf("%d%d",&n,&k);
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                scanf("%d",&init.a[i][j]);
            }
        Matrix res=quick_pow(init,k);
        int ans=0;
        for(int i=0; i<n; i++)
            ans=(ans+res.a[i][i])%mod;
        printf("%d\n",ans%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Imagirl1/article/details/82772125