BZOJ-1875 HH去散步 DP+矩阵乘法快速幂
1875: [SDOI2009]HH去散步
Time Limit: 20 Sec Memory Limit: 64 MB
Submit: 1196 Solved: 553
[Submit][Status][Discuss]
Description
HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径
Input
第一行:五个整数N,M,t,A,B。其中N表示学校里的路口的个数,M表示学校里的 路的条数,t表示HH想要散步的距离,A表示散步的出发点,而B则表示散步的终点。 接下来M行,每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。数据保证Ai = Bi,但 不保证任意两个路口之间至多只有一条路相连接。 路口编号从0到N − 1。 同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 答案模45989。
Output
一行,表示答案。
Sample Input
4 5 3 0 0
0 1
0 2
0 3
2 1
3 2
Sample Output
4
HINT
对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。 对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B
Source
Day1
其实这题应该不难,但是真的没想到正解....
题解:
正常是对点构造矩阵,那么这里用边来构造,保证走的时候不经过反向边即可,然后矩乘快速幂加速
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define maxn 25
#define maxm 70
#define p 45989
int n,m,t,st,ed;
struct data{int to,next;}edge[maxm*2];
int head[maxm],cnt;
int l,ans;
struct Mat{int a[maxm*2][maxm*2];Mat(){memset(a,0,sizeof(a));}};
void add(int u,int v)
{
cnt++;
edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt;
}
Mat mul(Mat A,Mat B)
{
Mat re;
for (int i=1; i<=l; i++)
for (int j=1; j<=l; j++)
for (int k=1; k<=l; k++)
re.a[i][j]=(re.a[i][j]+(A.a[i][k]*B.a[k][j])%p)%p;
return re;
}
Mat quick_mul(Mat A,int x)
{
Mat re;
for (int i=1; i<=l; i++) re.a[i][i]=1;
while (x)
{
if (x&1) re=mul(re,A);
x>>=1; A=mul(A,A);
}
return re;
}
int findre(int x)
{
if (x&1) return x+1;
else return x-1;
}
int main()
{
n=read(),m=read(),t=read(),st=read(),ed=read();
for (int i=1; i<=m; i++)
{
int u=read(),v=read();
add(u,v); add(v,u);
}
Mat x,y;
for (int i=head[st]; i; i=edge[i].next)
x.a[1][i]=1;
l=cnt;
if (t==0) {if (st==ed) puts("1"); else puts("0"); return 0;}
for (int i=1; i<=l; i++)
for (int j=head[edge[i].to]; j; j=edge[j].next)
if (j!=findre(i)) y.a[i][j]=1;
x=mul(x,quick_mul(y,t-1));
for (int i=head[ed]; i; i=edge[i].next)
ans=(ans+x.a[1][findre(i)])%p;
printf("%d\n",ans);
return 0;
}
BZOJ-1875 HH去散步 DP+矩阵乘法快速幂的更多相关文章
- BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)
题目链接 比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边 如果这样表示是不好转移的 可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 ...
- BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法
BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法 Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时H ...
- BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )
把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 ------------------------------------------------------------------ ...
- [BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】
题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边 ...
- BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)
首先,题意就把我们引向了矩阵乘法,注意边长m<=60,那么就按边建图,变成一个120个点的图,然后乱搞就行了。 PS:WA了N久改了3次终于A了QAQ CODE: #include<cst ...
- 1875. [SDOI2009]HH去散步【矩阵乘法】
Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...
- [SDOI2009]HH去散步 「矩阵乘法计数」
计数问题也许可以转化为矩阵乘法形式 比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可 故 矩阵乘法计数 对于计数问题,若可以将 \(n\) 个点表示成 \(n \ti ...
- [bzoj1875][SDOI2009] HH去散步 [dp+矩阵快速幂]
题面 传送门 正文 其实就是让你求有多少条长度为t的路径,但是有一个特殊条件:不能走过一条边以后又立刻反着走一次(如果两次经过同意条边中间隔了别的边是可以的) 如果没有这个特殊条件,我们很容易想到dp ...
- 【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)
2323: [ZJOI2011]细胞 Description 2222年,人类在银河系外的某颗星球上发现了生命,并且携带了一个细胞回到了地球.经过反复研究,人类已经完全掌握了这类细胞的发展规律: 这种 ...
随机推荐
- HDU 2487 Ugly Windows
递归求解,代码不太好看,是2013年7月写的 代码: #include<stdio.h> #include<iostream> #include<string.h> ...
- 三维网格去噪算法(bilateral filter)
受图像双边滤波算法的启发,[Fleishman et al. 2003]和[Jones et al. 2003]分别提出了利用双边滤波算法对噪声网格进行光顺去噪的算法,两篇文章都被收录于当年的SIGG ...
- 城堡 (spfa+cheng)
[问题描述] 给定一张?个点?条边的无向连通图,每条边有边权.我们需要从?条边中选出? − 1条, 构成一棵树. 记原图中从 1 号点到每个节点的最短路径长度为? ? ,树中从 1 号点到每个节点的最 ...
- JetBrain WebStorm 注册码
webStorm : UserName:William ===== LICENSE BEGIN ===== 45550-12042010 00001SzFN0n1bPII7FnAxnt0DDOPJA ...
- java9-2形式参数
1.形式参数: 基本类型(太简单) 引用类型 类名:(匿名对象的时候其实我们已经讲过了)需要的是该类的对象 抽象类:需要的是该抽象的类子类对象 接口:需要的是该接口的实现类对象 A. 类名:(匿名对象 ...
- ng-bind的使用
由于JS是单线程的,当HTML页面执行alert的时候,会中断下面代码的运行,所以为了良好的用户体验,当需要在页面使用{{name}}的时候,通常不这样直接输出,而是用ng-bind绑定model数据 ...
- KVM虚拟机网络基础及优化说明
一个完整的数据包从虚拟机到物理机的路径是: 虚拟机--QEMU虚拟网卡--虚拟化层--内核网桥--物理网卡 KVM的网络优化方案,总的来说,就是让虚拟机访问物理网卡的层数更少,直至对物理网卡的单独占领 ...
- Netty关闭客户端
在启动客户端的时候,我们一般会 channelFuture.channel().closeFuture().sync(); 这是一段阻塞的代码,除非链路断了,否则是不会终止的,我们可以在handler ...
- 第四章 在MVC4.0中对脚本以及样式表的引用变化
原文:http://www.cnblogs.com/xdotnet/archive/2012/07/21/aspnet40_webpage20.html 一.可以直接使用“~”,而无需使用Href对象 ...
- vue 2.0-1
vue 2.0 开发实践总结之疑难篇 续上一篇文章:vue2.0 开发实践总结之入门篇 ,如果没有看过的可以移步看一下. 本篇文章目录如下: 1. vue 组件的说明和使用 2. vuex在实 ...