POJ 3233 矩阵快速幂&二分

题意:
给你一个n*n的矩阵 让你求S:
思路:
只知道矩阵快速幂 然后nlogn递推是会TLE的。

所以呢 要把那个n换成log

那这个怎么搞呢

二分!

当k为偶数时:

当k为奇数时:

就按照这么搞就能搞出来了
(我是看的题解才A的,,, 中间乱搞的时候犯了一些脑残的错误)

// by SiriusRen
#include <cstdio>
#include <cstring>
using namespace std;
int n,mod,k;
struct matrix{int a[33][33];void init(){memset(a,0,sizeof(a));}}first;
matrix mul(matrix a,matrix b){
    matrix temp;temp.init();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                temp.a[i][j]=(temp.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
    return temp;
}
matrix add(matrix a,matrix b){
    matrix temp;temp.init();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
            temp.a[i][j]=(a.a[i][j]+b.a[i][j])%mod;
    return temp;
} 
matrix pow(matrix a,int x){
    matrix temp;
    x--;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            temp.a[i][j]=a.a[i][j];
    while(x){
        if(x&1)temp=mul(temp,a);
        a=mul(a,a),x>>=1;
    }
    return temp;
}
matrix recursive(int x){
    if(x==1)return first;
    matrix temp=recursive(x/2);
    if(x&1){
        matrix jy=pow(first,x/2+1);
        temp=add(temp,mul(temp,jy));
        return add(jy,temp);
    }
    else{
        matrix jy=pow(first,x/2);
        return add(mul(jy,temp),temp);
    }
}
int main(){
    scanf("%d%d%d",&n,&k,&mod);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            scanf("%d",&first.a[i][j]);
            first.a[i][j]=first.a[i][j]%mod;
        }
    matrix jy=recursive(k);
    for(int i=1;i<=n;i++){
        for(int j=1;j<n;j++)
            printf("%d ",jy.a[i][j]);
        printf("%d\n",jy.a[i][n]);
    }
}

这里写图片描述

posted @ 2016-07-20 22:30  SiriusRen  阅读(109)  评论(0编辑  收藏  举报