快速幂

普通快速幂

\(code :\)

ll qp(ll x,ll y)
{
	ll ans=1;
	while(y)
	{
		if(y&1) ans*=x;
		x*=x;
		y>>=1;
	}
	return ans;
}

有时配合龟速乘使用

\(code :\)

ll mul(ll x,ll y)
{
  	ll ans=0;
  	while(y) 
	{
		if(y&1) ans+=x;
		x+=x;
		y>>=1;
  	}
  	return ans;
}

\(O(1)\)快速乘

\(code :\)

ll mul(ll x,ll y,ll mod)
{
	return (x*y-(ll)((long double)x/mod*y)*mod+mod)%mod;
}

矩阵快速幂

\(code :\)

struct matrix
{
	ll a[maxn][maxn];
	matrix()
	{
		memset(a,0,sizeof(a));//要赋初值,不然会出锅
	}
}m,e;
matrix operator *(const matrix &x,const matrix &y)//重载矩阵乘法
{
    matrix z;
    for(int k=1;k<=n;++k)
    	for(int i=1;i<=n;++i)
        	for(int j=1;j<=n;++j)
        		z.a[i][j]+=x.a[i][k]*y.a[k][j];
	return z;
}
matrix qp(matrix x,ll y)
{
    matrix ans=e;
    while(y)
    {
        if(y&1) ans=ans*x; 
        x=x*x;
        y>>=1;
    }
    return ans;
}

......

for(int i=1;i<=n;++i) e.a[i][i]=1;//构造单位矩阵

通常用来矩阵加速,已知递推式,求数列第\(n\)

\(f[i]=f[i-3]+f[i-1]\ (i\geqslant 3)\)

先构造目标矩阵\(\begin{bmatrix} f[i]&f[i-1]&f[i-2]\end{bmatrix} \quad\)

\[f[i]=f[i-1]×1+f[i-2]×0+f[i-3]×1 \]

\[f[i-1]=f[i-1]×1+f[i-2]×0+f[i-3]×0 \]

\[f[i-2]=f[i-1]×0+f[i-2]×1+f[i-3]×0 \]

得到初始矩阵\(\begin{bmatrix} 1&1&0\\0&0&1\\1&0&0\end{bmatrix} \quad\)

初始矩阵进行\(n\)次方再乘上后\(\begin{bmatrix} f[0]&f[1]&f[2]\end{bmatrix} \quad\),第一行第二个元素即为\(f[n]\)

posted @ 2020-01-22 20:19  lhm_liu  阅读(116)  评论(0编辑  收藏  举报