zoukankan      html  css  js  c++  java
  • 学习笔记-矩阵十题

    快速幂模板

    #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表示的状态能被横着骨牌覆盖

  • 相关阅读:
    Android 多渠道打包,上百渠道,秒打签名
    Failed to collect certificates from /data/app/vmdl201020547.tmp/base.apk: META-INF/CERT.SF indicates /data/app/vmdl201020547.tmp/base.apk is signed using APK Signature Scheme v2, but no such signature
    React java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.edaixi.activity/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit
    Effective Java 电子书 apk版本下载
    javascript数组遍历的几种常用方法性能分析对比
    微信小程序开发——列表分页上拉加载封装实现(订单列表为例,订单状态改变后刷新列表滚动位置不变)
    微信小程序开发——点击防重的解决方案
    微信小程序开发——点击按钮退出小程序的实现
    css选择器的优先级
    html页面的CSS、DIV命名规则(仅供参考学习)
  • 原文地址:https://www.cnblogs.com/mukoiaoi/p/12656286.html
Copyright © 2011-2022 走看看