[SDOI2009]HH去散步 「矩阵乘法计数」
计数问题也许可以转化为矩阵乘法形式
比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可
故
矩阵乘法计数
对于计数问题,若可以将 \(n\) 个点表示成 \(n \times n\) 的矩阵,并且可以保证中途转移对象不会变化,即可用矩阵乘法计数
至于该题
那么考虑该题,加入了不能重复在一条边上走的限制,那么最简单的思想就是拆点,并且让改点屏蔽掉当前方向,但是如果考虑边,一条无向边可以拆成两条有向边,那拆出来的就比点少很多了,故考虑点边转化
那么只要在起始点加一条超级源边,同样矩阵乘法即可统计答案
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define MOD 45989
using namespace std;
typedef long long LL;
const int MAXN = 50 + 10;
const int MAXM = 120 + 10;
struct LinkedForwardStar {
int to;
int next;
} ;
LinkedForwardStar Link[MAXM];
int Head[MAXN]= {0};
int size = 1;
void Insert (int u, int v) {
Link[++ size].to = v;
Link[size].next = Head[u];
Head[u] = size;
}
int N, M, K;
int st, ed;
struct Matrix {
LL a[MAXM][MAXM];
void init () {
for (int i = 1; i <= size; i ++)
for (int j = 1; j <= size; j ++)
a[i][j] = 0;
}
Matrix operator * (const Matrix& p) const {
Matrix newmat;
newmat.init ();
for (int i = 1; i <= size; i ++)
for (int j = 1; j <= size; j ++)
for (int k = 1; k <= size; k ++)
newmat.a[i][j] = (newmat.a[i][j] + a[i][k] * p.a[k][j] % MOD) % MOD;
return newmat;
}
} ;
Matrix mats, bem;
LL power (int p) {
while (p) {
if (p & 1)
mats = mats * bem;
bem = bem * bem;
p >>= 1;
}
LL ans = 0;
for (int i = Head[ed]; i; i = Link[i].next)
ans = (ans + mats.a[1][i ^ 1]) % MOD;
return ans;
}
int getnum () {
int num = 0;
char ch = getchar ();
while (! isdigit (ch))
ch = getchar ();
while (isdigit (ch))
num = (num << 3) + (num << 1) + ch - '0', ch = getchar ();
return num;
}
int main () {
N = getnum (), M = getnum (), K = getnum (), st = getnum () + 1, ed = getnum () + 1;
for (int i = 1; i <= M; i ++) {
int u = getnum () + 1, v = getnum () + 1;
Insert (u, v), Insert (v, u);
}
for (int i = Head[st]; i; i = Link[i].next)
bem.a[1][i] = 1;
for (int i = 2; i <= size; i ++) {
int v = Link[i].to;
for (int j = Head[v]; j; j = Link[j].next) {
if ((j ^ 1) == i)
continue;
bem.a[i][j] = 1;
}
}
for (int i = 1; i <= size; i ++)
mats.a[i][i] = 1;
LL ans = power (K);
cout << ans << endl;
return 0;
}
/*
4 5 3 0 0
0 1
0 2
0 3
2 1
3 2
*/
[SDOI2009]HH去散步 「矩阵乘法计数」的更多相关文章
- BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法
BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法 Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时H ...
- 1875. [SDOI2009]HH去散步【矩阵乘法】
Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...
- BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)
首先,题意就把我们引向了矩阵乘法,注意边长m<=60,那么就按边建图,变成一个120个点的图,然后乱搞就行了。 PS:WA了N久改了3次终于A了QAQ CODE: #include<cst ...
- BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)
题目链接 比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边 如果这样表示是不好转移的 可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 ...
- BZOJ 1875 [SDOI2009]HH去散步 ——动态规划 矩阵乘法
发现t非常大,所以大概就是快速幂一类的问题了, 然后根据k^3logn算了算,发现k大约是边数的时候复杂度比较合适. 发现比较麻烦的就是前驱的记录,所以直接把边看做点,不能走反向边,但是可以走重边,然 ...
- BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )
把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 ------------------------------------------------------------------ ...
- BZOJ-1875 HH去散步 DP+矩阵乘法快速幂
1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 1196 Solved: 553 [Submit][Statu ...
- [BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】
题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边 ...
- [bzoj1875][SDOI2009] HH去散步 [dp+矩阵快速幂]
题面 传送门 正文 其实就是让你求有多少条长度为t的路径,但是有一个特殊条件:不能走过一条边以后又立刻反着走一次(如果两次经过同意条边中间隔了别的边是可以的) 如果没有这个特殊条件,我们很容易想到dp ...
随机推荐
- sqlserver附加数据库时,无法打开物理文件 "xx.mdf"。操作系统错误 5:"5
sqlserver在附加数据库时,提示无法打开物理文件 "xx.mdf".操作系统错误 5:"5 此时可能你是用window验证方式登陆数据库的? 如果是这样,断开连接, ...
- ElasticSearch 5.6.1 安装 Kibana、X-Pack和head
前面已经有写过ElasticSearch和iK的安装了这里就不在所了. 安装Kiabna 在下载tar包的时候需要注意下一安装的es版本号,按照官网的说明版本是对应一致的. https://www.e ...
- Linux用户和用户组管理
该内容来摘自于鸟叔的Linux私房菜. Linux的每个用户包含两个ID,一个是用户ID,一个是用户组ID.系统会根据/etc/passwd和/etc/group的设定来决定用户的访问权限.下面对用户 ...
- mybatis之一对一关联
MapperAsso.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper ...
- BOM之navigator对象和用户代理检测
前面的话 navigator对象现在已经成为识别客户端浏览器的事实标准,navigator对象是所有支持javascript的浏览器所共有的.本文将详细介绍navigator对象和用户代理检测 属性 ...
- 【bzoj4771】七彩树 树链的并+STL-set+DFS序+可持久化线段树
题目描述 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义 ...
- [代码]--WinForm 窗体之间相互嵌套
public FrmScan() { InitializeComponent(); Form1 frm = new Form1(); frm.Dock = DockStyle.Fill; frm.Fo ...
- 浅谈Java中的深克隆和浅克隆(阿里面试)
在最近的秋招中,阿里和多益网络都问到了这个问题,虽然很简单,但是我还是想总结一下,感兴趣的可以看一下我的个人博客网站(Spring+MyBatis+redis+nginx+mysql)(适合菜鸟),最 ...
- [COGS 2551] 新型武器
图片加载可能有点慢,请跳过题面先看题解,谢谢 这个题好多解法啊... 可以主席树,可以按深度将操作排序离线做 我这里是动态开点线段树,对每一个深度种一棵线段树,下标是节点的\(dfs\)序 然后这个做 ...
- 敏捷持续集成(Jenkins)
在前面已经完成git和gitlab的相关操作 1.持续集成的概念: 1. 什么是持续集成: 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可 ...