[SDOI 2009] HH去散步

[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=1875

[算法]

用f[i][j]表示现在在走了i步 , 在第j条边的方案数

矩阵加速 , 即可

时间复杂度 : O(N ^ 3logN)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 125
const int P = 45989;

struct edge
{
        int to , nxt;
} e[MAXN << 1];
int n , m , t , A , B , tot;
int head[MAXN];

struct matrix_t
{
        int mat[MAXN][MAXN];
} a , b;
template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
inline void addedge(int u,int v)
{
        tot++;
        e[tot] = (edge){v , head[u]};
        head[u] = tot;
}
inline void multipy(matrix_t &a , matrix_t b)
{
        static matrix_t ret;
        for (int i = 1; i <= tot; i++)
        {
                for (int j = 1; j <= tot; j++)
                {
                        ret.mat[i][j] = 0;
                }
        }
        for (int i = 1; i <= tot; i++)
        {
                for (int j = 1; j <= tot; j++)
                {
                        for (int k = 1; k <= tot; k++)
                        {
                                ret.mat[i][j] = (ret.mat[i][j] + 1LL * a.mat[i][k] * b.mat[k][j]) % P;
                        }
                }
        }
        a = ret;
}
inline void exp_mod(matrix_t &a , int t)
{
        static matrix_t tmp;
        for (int i = 1; i <= tot; i++)
        {
                for (int j = 1; j <= tot; j++)
                {
                        tmp.mat[i][j] = (i == j);
                }
        }
        while (t > 0)
        {
                if (t & 1) multipy(tmp , a);
                multipy(a , a);
                t >>= 1;
        }
        a = tmp;
}

int main()
{

        read(n); read(m); read(t); read(A); read(B);
        ++A; ++B;
        tot = 1;
        for (int i = 1; i <= m; i++)
        {
                int u , v;
                read(u); read(v);
                ++u; ++v;
                addedge(u , v);
                addedge(v , u);
        }
        for (int i = 2; i <= tot; i++)
        {
                for (int j = 2; j <= tot; j++)
                {
                        if (i != (j ^ 1) && e[j ^ 1].to == e[i].to)
                                ++b.mat[i][j];
                }
        }
        for (int i = head[A]; i; i = e[i].nxt) ++a.mat[1][i];
        exp_mod(b , t - 1);
        multipy(a , b);
        int ans = 0;
        for (int i = head[B]; i; i = e[i].nxt) ans = (ans + 1LL * a.mat[1][i ^ 1]) % P;
        printf("%d\n" , ans);

        return 0;

}

原文地址:https://www.cnblogs.com/evenbao/p/9858884.html

时间: 2024-10-19 06:16:57

[SDOI 2009] HH去散步的相关文章

[BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】

题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边看做点建矩阵,那么每次从一条边出发都只会到其他的边,不能仍然在这条边上“停留”,所以这就可以满足题目的限制.将每条边拆成两条单向边,比如一条编号为 4,一条编号为 5.那么 4^1=5, 5^1=4.这样只要不从第 i 条边走到 i 或 i^1 就可以了.初始的矩阵中以 A 为起点的边到达的方案数为

BZOJ 1875 SDOI 2009 HH去散步 矩阵乘法优化DP

题目大意:给出一张无向图,求从A到B走k步(不能走回头路)的方案数.(k <= 2^30) 思路:看到k的范围就知道是矩阵乘法了.关键是不能走回头路怎么构造.正常的方法构造点的转移不能避免这个问题,就用边来构造.只要保证不经过自己^1的边就可以保证不走回头路了. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX

BZOJ1875: [SDOI2009]HH去散步

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 620  Solved: 265[Submit][Status] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法.

bzoj 1875: [SDOI2009]HH去散步 -- 矩阵乘法

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MB Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每 天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法. 现在给你学校的地图(假设每条路的长度都 是一样的都是1),问长度为t,从给定

BZOJ 1875[SDOI2009]HH去散步

题面: 1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1750  Solved: 851[Submit][Status][Discuss] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每 天走过的路径都不完全一样,他想知

【bzoj1875】【SDOI2009】【HH去散步】

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 932 Solved: 424 [Submit][Status][Discuss] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多

BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )

把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MOD = 45989; const int

BZOj-1875: [SDOI2009]HH去散步 (矩阵快速幂)

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1999  Solved: 980[Submit][Status][Discuss] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每 天走过的路径都不完全一样,他想知道他究竟

[SDOI2009]HH去散步

[SDOI2009]HH去散步 题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法. 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径 输入输出格式 输入格式: 第一行:五个整数N,M,t,A,B.其