HDU5411CRB and Puzzle(矩阵高速幂)

题目链接:传送门

题意:

一个图有n个顶点。已知邻接矩阵。问点能够反复用长度小于m的路径有多少。

分析:

首先我们知道了邻接矩阵A。那么A^k代表的就是长度为k的路径有多少个。

那么结果就是A^0+A^1+A^2+...+A^m。

然后我们能够构造一个矩阵来帮助我们求解。

X = | A , E |

| 0 , E |

==> 然后X^m 的矩阵的右上角的矩阵代表的就是A^0+A^1+A^2+...+A^m。

当然A^0+A^1+A^2+...+A^m,也能够用二分来求。

代码例如以下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 51*2;

const int mod = 2015;

typedef long long LL;

struct matrix{
    int a[maxn][maxn];
    matrix(){
        memset(a,0,sizeof(a));
    }
};

matrix I;

void init(){
    for(int i=0;i<maxn;i++)
        I.a[i][i]=1;
}

int n,m;

matrix multi(matrix A,matrix B){
    matrix C;
    for(int i=0;i<2*n;i++){
        for(int j=0;j<2*n;j++){
            for(int k=0;k<2*n;k++){
                C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]);
            }
            C.a[i][j]%=mod;
        }
    }
    return C;
}

matrix add(matrix A,matrix B){
    matrix C;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            C.a[i][j]=(A.a[i][j]+B.a[i][j])%mod;
        }
    }
    return C;
}

int quick_mod(matrix A,int b){
    matrix ans = I;
    while(b){
        if(b&1) ans = multi(ans,A);
        b>>=1;
        A=multi(A,A);
    }
    int sum = 0;
    for(int i=0;i<n;i++){
        for(int j=n;j<n*2;j++)
            sum=sum+ans.a[i][j];
    }
//    cout<<"----------ans------------"<<endl;
//    for(int i=0;i<2*n;i++){
//        for(int j=0;j<2*n;j++)
//            cout<<ans.a[i][j]<<" ";
//        cout<<endl;
//    }
//    cout<<"----------ans------------"<<endl;
    return sum%mod;
}

int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        matrix A,B;
        for(int i=0;i<n;i++){
            int k,u;
            scanf("%d",&k);
            while(k--){
                scanf("%d",&u);
                A.a[i][--u]=1;
            }
        }
        for(int i=0;i<n;i++) A.a[i][i+n]=1;
        for(int i=n;i<2*n;i++) A.a[i][i]=1;
//        cout<<"----------A------------"<<endl;
//        for(int i=0;i<2*n;i++){
//            for(int j=0;j<2*n;j++)
//                cout<<A.a[i][j]<<" ";
//            cout<<endl;
//        }
//        cout<<"----------A------------"<<endl;
        int sum = quick_mod(A,m);
        printf("%d\n",sum+1);
    }
    return 0;
}
时间: 2024-10-27 16:58:59

HDU5411CRB and Puzzle(矩阵高速幂)的相关文章

hdu 5411 CRB and Puzzle 矩阵高速幂

链接 题解链接:http://www.cygmasot.com/index.php/2015/08/20/hdu_5411/ 给定n个点 常数m 以下n行第i行第一个数字表示i点的出边数.后面给出这些出边. 问:图里存在多少条路径使得路径长度<=m.路径上的点能够反复. 思路: 首先能得到一个m*n*n的dp.dp[i][j]表示路径长度为i 路径的结尾为j的路径个数 . 答案就是sigma(dp[i][j]) for every i from 1 to m, j from 1 to n; 我们

HDOJ 5411 CRB and Puzzle 矩阵高速幂

直接构造矩阵,最上面一行加一排1.高速幂计算矩阵的m次方,统计第一行的和 CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 133    Accepted Submission(s): 63 Problem Description CRB is now playing Jigsaw Puzzle. There

HDU 5411 CRB and puzzle (Dp + 矩阵高速幂)

CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 483    Accepted Submission(s): 198 Problem Description CRB is now playing Jigsaw Puzzle. There are  kinds of pieces with infinite

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

HDU3117-Fibonacci Numbers(矩阵高速幂+log)

题目链接 题意:斐波那契数列,当长度大于8时.要输出前四位和后四位 思路:后四位非常easy,矩阵高速幂取模,难度在于前四位的求解. 已知斐波那契数列的通项公式:f(n) = (1 / sqrt(5)) * (((1 + sqrt(5)) / 2) ^ n - ((1 + sqrt(5)) / 2) ^ n).当n >= 40时((1 + sqrt(5)) / 2) ^ n近似为0. 所以我们如果f(n) = t * 10 ^ k(t为小数),所以当两边同一时候取对数时.log10(t * 10

HDOJ 4686 Arc of Dream 矩阵高速幂

矩阵高速幂: 依据关系够建矩阵 , 高速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2164    Accepted Submission(s): 680 Problem Description An Arc of Dream is a curve defined by following fun

HDU 4965 Fast Matrix Calculation(矩阵高速幂)

HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次.能够变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个仅仅有6x6.就能够用矩阵高速幂搞了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int M = 10; int n, m; int A[N][M], B[M][N], C[M][M], CC[N

hdu 5318 The Goddess Of The Moon 矩阵高速幂

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5318 The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 438    Accepted Submission(s): 150 Problem Description Chang'e (嫦娥) is

HDU 2604 Queuing 矩阵高速幂

QueuingTime Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2483    Accepted Submission(s): 1169 Problem Description Queues and Priority Queues are data structures which are known to most computer s