• 学习笔记-矩阵十题


    快速幂模板

    #define N 150
    struct martix{
        LL mar[N][N];
        martix(){
            memset(mar,0,sizeof (mar));
        }
        inline void build(){
            FOR(i,0,N) mar[i][i]=1;
            return;
    
        }
        inline void clear(){
            memset(mar,0,sizeof (mar));
            return;
        }
    } aa;
    martix operator *(const martix &a, const martix &b){
        martix c;
        //c.clear();
        FOR(k,0,N)
        FOR(i,0,N){
        if(a.mar[i][k]<=0) continue; 
        FOR(j,0,N){
        if(b.mar[k][j]<=0) continue; 
        c.mar[i][j]+=a.mar[i][k]*b.mar[k][j];
        }
        }
        return c;
    }
    martix operator ^( martix  a, LL k){
        martix x=a,tmp;
        LL pow=k;
        tmp.clear();tmp.build();
        while(pow){
            if(pow&1) tmp=x*tmp;
            x=x*x;
            pow>>=1;
        }
        return tmp;
    }
    模板

    需要注意的说开200X200以上可能爆栈,这时候必须把封装去了

    技巧1:对矩阵Ak次幂求和可以构造矩阵

    A E

    0 E

    新矩阵的k+1次幂的右上即为所求

    技巧2:齐次递推数列可以构造矩阵快速求出

    将所有项看作列向量就可以很方便地构造,若要求多项和,只需在构造的矩阵中加一列即可

    技巧3:从u到v恰好走k步

    转移矩阵k次幂即可

    VIJOS 1049 

    //#define LOCAL
    #include <cstring>
    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <functional>
    #include <utility>
    #include <bitset>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <cstdio>
    using namespace std;
    #define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
    // X_INIT=0  mem_Macro
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    #define FOR(i,j,k) for(int i=j;i<k;i+=1)
    #define FORD(i,j,k) for(int i=j;i>k;i-=1)
    #define uLL unsigned long long
    #define LL long long
    #define SZ(x) int(x.size())
    #define pb push_back
    #define N 150
    //int MOD;
    struct martix{
        LL mar[N][N];
        martix(){
            memset(mar,0,sizeof (mar));
        }
        inline void build(){
            FOR(i,0,N) mar[i][i]=1;
            return;
    
        }
        inline void clear(){
            memset(mar,0,sizeof (mar));
            return;
        }
    } aa;
    martix operator *(const martix &a, const martix &b){
        martix c;
        //c.clear();
        FOR(k,0,N)
        FOR(i,0,N){
        if(a.mar[i][k]<=0) continue; 
        FOR(j,0,N){
        if(b.mar[k][j]<=0) continue; 
        c.mar[i][j]+=a.mar[i][k]*b.mar[k][j];
       // c.mar[i][j]%=MOD;
        }
        }
        return c;
    }
    martix operator ^( martix  a, LL k){
        martix x=a,tmp;
        LL pow=k;
        tmp.clear();tmp.build();
        while(pow){
            if(pow&1) tmp=x*tmp;
            x=x*x;
            pow>>=1;
        }
        return tmp;
    }
    int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    int a[11][110];
    //cout<<"*";
    martix tmp,ans;
    ans.build();
    FOR(i,0,m){
        tmp.clear();
        FOR(j,0,n)
        scanf("%d",&a[i][j]),tmp.mar[j][a[i][j]-1]=1;
        ans=tmp*ans;
    }
    ans=ans^(k/m);
    FOR(i,0,k%m){
        tmp.clear();
        FOR(j,0,n)
        tmp.mar[j][a[i][j]-1]=1;
        ans=tmp*ans;
    }
    int anss[110];
    FOR(i,0,n)
    FOR(j,0,n)
    if(ans.mar[i][j]) anss[i]=j;
    /*FOR(i,0,n)
    {FOR(j,0,n)
    cout<<tmp.mar[i][j];
    cout<<endl;
    }
    
    FOR(i,0,k%m)
    FOR(j,0,n)
    anss[j]=anss[a[i][j]-1];
    //anss[j]=a[i][j]-1;*/
    FOR(i,0,n)
    cout<<anss[i]+1<<' ';
    //system("pause");
    #ifdef LOCAL
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
    }
    ac代码

    VIJOS 1194

    //#define LOCAL
    #include <cstring>
    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <functional>
    #include <utility>
    #include <bitset>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <cstdio>
    using namespace std;
    #define X_mem(x,y,z) (X_mem[x][y][z] ? X_mem[x][y][z] :X_mem[x][y][z]=mem(x,y,z))
    // X_INIT=0  mem_Macro
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    #define FOR(i,j,k) for(int i=j;i<k;i+=1)
    #define FORD(i,j,k) for(int i=j;i>k;i-=1)
    #define uLL unsigned long long
    #define LL long long
    #define SZ(x) int(x.size())
    #define pb push_back
    #define N 150
    //int MOD;
    int p;
    struct martix{
        LL mar[N][N];
        martix(){
            memset(mar,0,sizeof (mar));
        }
        inline void build(){
            FOR(i,0,N) mar[i][i]=1;
            return;
    
        }
        inline void clear(){
            memset(mar,0,sizeof (mar));
            return;
        }
    } aa;
    martix operator *(const martix &a, const martix &b){
        martix c;
        //c.clear();
        FOR(k,0,N)
        FOR(i,0,N){
        if(a.mar[i][k]<=0) continue; 
        FOR(j,0,N){
        if(b.mar[k][j]<=0) continue; 
        c.mar[i][j]+=a.mar[i][k]*b.mar[k][j];
        c.mar[i][j]%=p;
        }
        }
        return c;
    }
    martix operator ^( martix  a, LL k){
        martix x=a,tmp;
        LL pow=k;
        tmp.clear();tmp.build();
        while(pow){
            if(pow&1) tmp=x*tmp;
            x=x*x;
            pow>>=1;
        }
        return tmp;
    }
    int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d%d",&n,&m,&p);
    map<int,int> idx;
    idx[0]=1;idx[3]=1;idx[6]=1;idx[12]=1;idx[15]=1;idx[24]=1;idx[27]=1;idx[30]=1;
    int l=1<<m;
    FOR(i,0,l)
    FOR(j,0,l){
    if((i|j)==l-1)if(idx[(i)&j]) aa.mar[i][j]=1;
    }
    
    aa=aa^n;/*
    FOR(i,0,l){
    FOR(j,0,l)
    cout<<aa.mar[i][j];
    cout<<endl;}*/
    cout<<aa.mar[l-1][l-1];
    #ifdef LOCAL
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
    }
    ac代码

    神题,要求用1x2全覆盖NxM

    由于n,m极度的不均匀(m<5,n<1e9),而1X2最多影响两行,所以考虑一个状态转移矩阵

    状态为单独一行被覆盖的格子的二进制表示,预设前面的行已经被全覆盖。则步进的状态转移就可以看作在全覆盖当前行且最大影响范围不超过下一行的前提下任意的摆放结果(只看下一行的覆盖情况)

    转移的条件是(i|j)==1<<m-1(保证前一行被全覆盖,因为如过前一行这一位被覆盖,则无关紧要必为1,否则则需要下一行这一位为一(骨牌竖放))和i&j表示的状态能被横着骨牌覆盖

  • 相关阅读:
    asp.net如何实现删除文件的操作? (转)
    开始计算机英语的学习,先把这里当生词本用了。
    CSS Box Model 盒子模型
    生成网站快捷方式
    Microsoft .NET Framework 3.5 sp1离线安装解决方案
    asp.net生成网站快捷方式
    https://mail.google.com/tasks/ig?pli=1
    Sql server DATEDIFF DATEADD
    局域网 跨数据库 访问数据库
    asp.net 生成网站快捷方式
  • 原文地址:https://www.cnblogs.com/mukoiaoi/p/12656286.html
Copyright © 2020-2023  润新知