zoukankan      html  css  js  c++  java
  • Luogu P4159 [SCOI2009]迷路 矩阵快速幂+精巧转化

    大致就是矩阵快速幂吧。。

    这个时候会发现这些边权$le 9$,然后瞬间想到上回一道题:是不是可以建一堆转移矩阵再建一个$lcm(1,2,3,4,5,6,7,8,9)$的矩阵?。。。后来发现十分的慢qwq也好像不对

    于是考虑转化一下:首先把点$u$建成九个点,$P(u,i)$表示$u$点的第$i$个子点(其实就是计算编号用的).

    先初始化,把所有u的点依次连上边权为1的边

    然后比如有一条$(u,v)=x$的边,我们就把$P(u,x)与P(v,1)$连边(是不是十分精妙)

    然后快速幂,搞定!

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    const int N=128,M=2009;
    #define R register int
    #define P(i,j) (9*(i-1)+j)
    using namespace std;
    struct Mat {
        int sz,m[N][N];
        inline void clear() {memset(m,0,sizeof(m));}
        inline Mat() {clear(); sz=0;}
        inline Mat operator * (const Mat& x)const { register Mat ret; ret.sz=sz;
            for(R i=1;i<=sz;++i) for(R k=1;k<=sz;++k) for(R j=1;j<=sz;++j) 
                (ret.m[i][j]+=m[i][k]*x.m[k][j]%M)%=M; return ret;
        }
        inline void operator *= (const Mat& x) {*this=(*this)*x;}
        inline void e() {clear(); for(R i=1;i<=sz;++i) m[i][i]=1;}
        inline Mat operator ^ (int b) { register Mat ret,a=(*this); ret.sz=sz; ret.e();
            for(;b;b>>=1,a*=a) if(b&1) ret*=a; return ret;
        }
    }a;
    int n,k;
    signed main() {
        scanf("%d%d",&n,&k); R n0=n; n*=9; a.sz=n;
        for(R i=1;i<=n0;++i) for(R j=1;j<=8;++j) a.m[P(i,j)][P(i,j+1)]=1;
        for(R i=1;i<=n0;++i) for(R j=1;j<=n0;++j) { R x;
            scanf("%1d",&x); if(x>0) a.m[P(i,x)][P(j,1)]=1;
        } a=a^k; printf("%d",a.m[1][P(n0,1)]);
    }

    2019.05.25

  • 相关阅读:
    JavaScript 正则表达式
    android源代码提示文本框还能输入多少个字符
    js实现鼠标点击input框后里面的内容就消失代码
    使用prompt输入一句英文句子和排序方式(升/降),将所有单词按排序方式排序后在网页上输出
    Javascript输出表格
    flutter 按键监听
    3.声明
    2.基础类型
    1.安装TypeScrpit
    苹果app证书
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10923209.html
Copyright © 2011-2022 走看看