zoukankan      html  css  js  c++  java
  • 矩阵快速幂——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;
    }
  • 相关阅读:
    Hosts文件的使用
    【java】关于时间
    【java】定时器
    log4j2的使用
    【springMVC】简单的前后端数据交流
    springMVC简单示例
    442. Find All Duplicates in an Array
    448. Find All Numbers Disappeared in an Array Add to List
    xml scheme 示例解析
    《C#高效编程》读书笔记04-使用Conditional特性而不是#if条件编译
  • 原文地址:https://www.cnblogs.com/helman/p/11323586.html
Copyright © 2011-2022 走看看