矩阵快速幂——POJ

题目链接

题目含义

对于n只猫,现在我们有g,e,s三种操作

g是让第a只猫得到一个花生

e是让第a只猫的花生全部没有

s是让第a只猫和第b只猫的花生互换

一共有K次操作,这还不算完

要我们重复m次这些操作后,得出的每只猫的花生个数

题目分析

如果不用重复m次操作的话,这道题可以说十分简单

但如果要重复m次,尤其m是个很大的数,那我们就要需要一个幂矩阵代替m

让每次的状态乘以幂矩阵就变成下一次的状态

而这个幂矩阵其实就是单位矩阵的变形,跟线性代数里的初等矩阵差不多

题目代码

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long LL;
const int maxn=107;
const LL mod=2147493647;
struct mat{
    LL m[maxn][maxn];
    int x,y;///x是行,y是列
}unit;
void init_unit(){
    memset(unit.m,0,sizeof(unit.m));
    for(int i=0;i<maxn;i++)
        unit.m[i][i]=1;
}
mat mat_mul(mat a,mat b){
    mat c;
    c.x=a.x,c.y=b.y;
    memset(c.m,0,sizeof(c.m));
    int i,j,k;
    for(i=1;i<=a.x;i++)
    for(k=1;k<=a.y;k++){
        if(!a.m[i][k])continue;
        for(j=1;j<=b.y;j++)
            c.m[i][j]+=(a.m[i][k]*b.m[k][j])/*%mod*/;
        //c.m[i][j]%=mod;
    }
    return c;
}
mat mat_pow(mat a,LL b){
    mat ans=unit;
    ans.x=a.x;
    ans.y=a.y;
    while(b){
        if(b&1)
            ans=mat_mul(ans,a);
        a=mat_mul(a,a);
        b>>=1;
    }
    return ans;
}
int n,k,x,y;
LL m;
char ch[10];
int main(){
    init_unit();
    while(scanf("%d%lld%d",&n,&m,&k)){
        if(!n&&!m&&!k)break;
        mat a,b=unit;
        a.x=1,a.y=n+1;
        for(int i=1;i<=n;i++)
            a.m[1][i]=0;
        a.m[1][n+1]=1;
        b.x=b.y=n+1;
//        b=unit;
        while(k--){
            scanf("%s",ch);
            if(ch[0]=='g'){
                scanf("%d",&x);
                b.m[n+1][x]++;
            }
            else if(ch[0]=='e'){
                scanf("%d",&x);
                for(int i=1;i<=n+1;i++)
                    b.m[i][x]=0;
            }
            else {
                scanf("%d%d",&x,&y);
                for(int i=1;i<=n+1;i++)
                    swap(b.m[i][x],b.m[i][y]);
            }
        }
        b=mat_pow(b,m);
        a=mat_mul(a,b);
        for(int i=1;i<=n;i++)
            printf("%lld ",a.m[1][i]);
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/helman/p/11323586.html