矩阵快速幂专题

占坑---------

-----填坑------

vj开的专题 密码1234589

数论_矩阵

codeforces-450B

题意:f1=x,f2=y,fi=fi-1+fi+1,输入x,y,和n,求fn%1e9+7

思路:fi=fi-1+fi+1,fi+1=fi+fi+2,俩式相加得 fi+2=-fi-1,矩阵快速幂

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int N=2;
const ll mod=1e9+7;
struct Mat{
    ll m[N][N];
    Mat(){
        mem(m);
    }
    Mat friend operator* (Mat a, Mat b){
        Mat c;
        for(int i=0; i<N; i++)
            for(int j=0; j<N; j++)
            for(int k=0; k<N; k++)
                c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
        return c;
    }
};
Mat PowMod(Mat a, ll b){
    Mat c;
    for(int i=0; i<N; ++i) c.m[i][i]=1;
    while(b){
        if(b&1) c=c*a;
        a=a*a;
        b>>=1;
    }
    return c;
}
int main(){
    ll aa[10],n;
    while(scanf("%I64d%I64d%I64d",&aa[1],&aa[2],&n)!=EOF){
        Mat a,s;
        a.m[0][0]=aa[2],a.m[0][1]=-aa[1];
        s.m[0][0]=1,s.m[1][0]=1,s.m[0][1]=-1;
        a=a*PowMod(s,n-2>0?n-2:0);
        printf("%I64d\n",n-2>0?(a.m[0][0]+mod)%mod:(aa[n]+mod)%mod);
    }
    return 0;
}
View Code

HDU 4965

题意:给你一个k,n,接下来是一个n*k的矩阵A,和k*n的矩阵B,矩阵A*B得到矩阵C,求C^n*n矩阵里面所有元素的和

思路:如果不做处理直接矩阵快速幂,N^3lgN的时间复杂度肯定吃不消,但是这里n很大,k很小,A*B 是n*n矩阵,B*A就是K*K的矩阵,所以写成A*(B*A)^n*n-1*B 就可以了

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int mod=6;
const int N=6;
struct Mat{
    int m[N][N];
    Mat(){
        mem(m);
    }
    friend Mat operator* (Mat a, Mat b){
        Mat c;
        for(int i=0; i<N; ++i)
        for(int j=0; j<N; ++j)
        for(int k=0; k<N; ++k)
        c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
        return c;
    }
};
Mat PowMod(Mat s, int b){
    Mat ans;
    for(int i=0; i<N; ++i) ans.m[i][i]=1;
    while(b){
        if(b&1) ans=ans*s;
        s=s*s;
        b>>=1;
    }
    return ans;
}
int c[1005][10],d[1005][1005];
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)&&(n||k)){
        Mat s;
        mem(c),mem(d);
        int a[1005][10],b[10][1005];
        for(int i=0; i<n; ++i)
            for(int j=0; j<k; ++j)
            scanf("%d",&a[i][j]);
        for(int i=0; i<k; ++i)
            for(int j=0; j<n; ++j)
            scanf("%d",&b[i][j]);
        for(int i=0; i<k; ++i)
            for(int j=0; j<k; ++j)
                for(int l=0; l<n; ++l)
                    s.m[i][j]=(s.m[i][j]+b[i][l]*a[l][j])%mod;
        s=PowMod(s,n*n-1);           //for(int i=0; i<k; ++i){for(int j=0; j<k; ++j) cout<<s.m[i][j]<<" ";cout<<endl;}
        for(int i=0; i<n; ++i)
            for(int j=0; j<k; ++j)
                for(int l=0; l<k; ++l)
                    c[i][j]=(c[i][j]+a[i][l]*s.m[l][j])%mod;
        int sum=0;
        for(int i=0; i<n; ++i)
            for(int j=0; j<n; ++j)
                for(int l=0; l<k; ++l)
                    d[i][j]=(d[i][j]+c[i][l]*b[l][j])%mod;
        for(int i=0; i<n; ++i)
            for(int j=0; j<n; ++j)
                sum+=d[i][j];
        printf("%d\n",sum);
    }
   return 0;
}
View Code

 

posted on 2016-12-06 08:02  lazzzy  阅读(206)  评论(0编辑  收藏  举报

导航