zoukankan      html  css  js  c++  java
  • [SDOI2009] HH去散步 (矩阵乘法)

    link

    $solution:$

    将边化为点后重新建矩阵,跑$T-1$幂即可(因为跑的是新边)。

    最后直接找与$x,y$所相连的边即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define int long long
    #define mod 45989
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=101;
    struct Matrix{
        int a[MAXN<<1][MAXN<<1];
        void init(){memset(a,0,sizeof(a));return;}
    }F,G;
    int cnt,n,m,A,B,T,sta[MAXN][MAXN<<1],End[MAXN<<1];
    Matrix operator*(Matrix x1,Matrix x2){
        Matrix x3;x3.init();
        for(int i=1;i<=(m<<1);i++)
            for(int k=1;k<=(m<<1);k++)
                for(int j=1;j<=(m<<1);j++) x3.a[i][j]+=x1.a[i][k]*x2.a[k][j],x3.a[i][j]%=mod;
        return x3;
    }
    Matrix ksm(Matrix a,int b){
        Matrix ans;ans.init();
        for(int i=1;i<=(m<<1);i++) ans.a[i][i]=1;
        while(b){
            if(b&1) ans=ans*a;
            a=a*a,b>>=1;
        }return ans;
    }int ans;
    int uu[MAXN<<1],vv[MAXN<<1];
    bool check(int idi,int idj){
        if(vv[idi]==uu[idj]) return 1;
        return 0;
    }
    signed main(){
        n=read(),m=read(),T=read(),A=read()+1,B=read()+1;
        for(int i=1;i<=m;i++){
            int u=read()+1,v=read()+1;
            if(v==B) End[++End[0]]=i;
            if(u==B) End[++End[0]]=i+m; 
            sta[u][++sta[u][0]]=i;
            uu[i]=u,vv[i]=v;
            sta[v][++sta[v][0]]=i+m;
            uu[i+m]=v,vv[i+m]=u;
        }F.init(),G.init();
        for(int i=1;i<=(m<<1);i++){
            for(int j=1;j<=(m<<1);j++) if(check(i,j)&&(i+m!=j&&j+m!=i)) G.a[i][j]=1;
        }
        //print(G);
        //printf("=========================
    ");
        F=ksm(G,T-1);
        //print(F);
        //for(int i=1;i<=End[0];i++) printf("End(%d):%d
    ",i,End[i]);
        //for(int i=1;i<=sta[A][0];i++) printf("sta(%d):%d
    ",i,sta[A][i]);
        for(int i=1;i<=sta[A][0];i++)
            for(int j=1;j<=End[0];j++) ans+=F.a[sta[A][i]][End[j]],ans%=mod;
        printf("%lld
    ",ans); 
    }
    View Code
  • 相关阅读:
    ThinkPHP的ajaxReturn方法的使用
    PHP中如何获取网站根目录物理路径
    MySQL索引覆盖
    php对gzip的使用(实例)
    php对gzip的使用(开启)
    php对gzip的使用(理论)
    ThinkPHP中调用PHPExcel
    PHPExcel正确读取excel表格时间单元格(转载)
    Kubernetes pod网络解析
    vRO 添加已有磁盘到VM
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10601789.html
Copyright © 2011-2022 走看看