BZOJ3583 杰杰的女性朋友 矩阵
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3583.html
题目传送门 - BZOJ3583
题意
有一个 $n$ 个点构成的有向图。
对于每一个点 $i$ ,给定两组参数,每组参数分别有 $k$ 个值。这两组参数分别记做: $in[i][1\cdots k],out[i][1\cdots k]$ 。
从点 $i$ 连到点 $j$ 的边数定义为 $\sum_{t=1}^k in[i][t]\times out[i][t]$ 。
$m$ 组询问,每次询问从 点 $x$ 走到点 $y$ ,经过不超过 $d$ 条边的方案总数。
$n\leq 1000,m\leq 50,k\leq 20,d\leq 2^{31}-1$
题解
首先我们选取 $k$ 个中介点,很容易得到一个由原图的 $n$ 个点转移到这 $k$ 个点的方案数的转移矩阵 $\mathbf O$;类似的,可以得一个由 $k$ 个中介点转移到原图的 $n$ 个点的方案数的转移矩阵 $\mathbf I$ 。
假设我们要求的是恰好经过 $d$ 条路径的方案数,那么,显然,我们只需要求出 $(\mathbf{OI})^d$ 的第 $i$ 行第 $j$ 列的值即可。
但是我们发现这个矩阵是 $1000\times 1000$ 的,复杂度显然不行。我们发现 $k$ 非常小,而且矩阵 $\mathbf {IO}$ 的长宽都是 $k$ 。
由于矩阵乘法具有结合律,所以我们可以把原式写成:
$\mathbf{O} (\mathbf{IO})^d \mathbf{I}$ 这样时间复杂度就对了。
但是原题要求的是不超过 $d$ 步的。
考虑新增一个点,这个点只能走到自己,将询问中的终点连向它即可。
代码
#pragma GCC optimize("O2")
#include <bits/stdc++.h>
using namespace std;
const int N=1005,K=25,mod=1e9+7;
struct Mat{int r,c;vector <vector <int> > v;Mat(){}Mat(int _r,int _c,int x){r=_r,c=_c;vector <int> vec;vec.clear();for (int i=0;i<=c;i++)vec.push_back(0);v.clear();for (int i=0;i<=r;i++)v.push_back(vec);if (r==c)for (int i=0;i<=r;i++)v[i][i]=x;}void Print(){for (int i=0;i<=r;i++,puts(""))for (int j=0;j<=c;j++)printf("%3d ",v[i][j]);puts("");}
};
Mat operator * (Mat A,Mat B){Mat C(A.r,B.c,0);if (A.c!=B.r)return C;for (int i=0;i<=A.r;i++)for (int j=0;j<=B.c;j++)for (int k=0;k<=A.c;k++)C.v[i][j]=(1LL*A.v[i][k]*B.v[k][j]+C.v[i][j])%mod;return C;
}
Mat Pow(Mat x,int y){Mat ans(x.r,x.c,1);for (;y;y>>=1,x=x*x)if (y&1)ans=ans*x;return ans;
}
int read(){int x=0;char ch=getchar();while (!isdigit(ch))ch=getchar();while (isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();return x;
}
int n,m,k;
Mat I,O,M,res;
int main(){n=read(),k=read();O=Mat(n,k,0);I=Mat(k,n,0);for (int i=1;i<=n;i++){for (int j=1;j<=k;j++)O.v[i][j]=read();for (int j=1;j<=k;j++)I.v[j][i]=read();}I.v[0][0]=O.v[0][0]=1;m=read();while (m--){int x=read(),y=read(),d=read();O.v[y][0]=1;res=O*Pow(I*O,d);int ans=0;for (int i=0;i<=k;i++)ans=(1LL*res.v[x][i]*I.v[i][0]+ans)%mod;printf("%d\n",ans);O.v[y][0]=0;}return 0;
}
转载于:https://www.cnblogs.com/zhouzhendong/p/BZOJ3583.html
BZOJ3583 杰杰的女性朋友 矩阵相关推荐
- [BZOJ3583]杰杰的女性朋友(矩阵快速幂)
杰杰的女性朋友 时间限制:10s 空间限制:256MB 题目描述 杰杰是魔法界的一名传奇人物.他对魔法具有深刻的洞察力,惊人的领悟力,以及令人叹为观止的创造力.自从他从事魔法竞赛以来,短短几 ...
- Bzoj3583 杰杰的女性朋友
Time Limit: 10 Sec Memory Limit: 256 MB Submit: 190 Solved: 98 Description 杰杰是魔法界的一名传奇人物.他对魔法具有深刻的 ...
- 刷题集--杰杰的女性朋友
题意:杰杰是魔法界的一名传奇人物.他对魔法具有深刻的洞察力,惊人的领悟力,以及令人叹为观止的创造力.自从他从事魔法竞赛以来,短短几年时间,就已经成为世界公认的实力最强的魔法选手之一.更让人惊叹的是,他 ...
- jzoj3545. 【清华集训2014】杰杰的女性朋友
Description 杰杰是魔法界的一名传奇人物.他对魔法具有深刻的洞察力,惊人的领悟力,以及令人叹为观止的创造力.自从他从事魔法竞赛以来,短短几年时间,就已经成为世界公认的实力最强的魔法选手之一. ...
- 欢迎进入杰杰的博客导航一站式搜索(所有博客的汇总帖)
网络的好朋友,你好,我是杰杰!如果我的博客有什么不足的地方,欢迎向我反馈:如果我的博客对你有帮助,那是我的荣幸!如果觉得文章很好,欢迎动动小手指,点个赞或者转发 -----杰杰. 欢迎关注我个人微信公 ...
- 为什么女性朋友容易患上拇外翻?
在生活中,我们常常可以看到不少女性朋友受到拇外翻的困扰.很多女性都是由于长期穿高跟鞋最终导致患上拇外翻的发生,患上拇外翻多数都是女性,这种疾病不仅影响美观,对健康也会产生严重的影响.那么为什么女性朋友 ...
- 适合给女性朋友过生日时发的祝福短信
朋友生日的日子你还记得吗?在自己的朋友生日到来的时候我们需要送上祝福,送上生日祝福能够让朋友充满幸福感.怎么写给朋友的生日祝福语呢?欢迎大家阅读小编为大家收集整理的<给女性朋友的生日祝福短信&g ...
- Seeker的奇妙求职冒险(杰杰的字节笔试)
替换后的最长重复字符 力扣原题424:https://leetcode-cn.com/problems/longest-repeating-character-replacement/ 题目大意: 给 ...
- 杰杰带你解读【机智云】环形缓冲区源码
前言 大家晚上好,我是杰杰,上个星期,研究了一下机智云的源码,也不能说是研究吧,就是看了看,人家既然能拿来做商业用,还是有很厉害的地方的,如果还不知道什么叫环形缓冲区(环形队列)的同学,请看--STM ...
最新文章
- C语言中浮点型在计算机中的存储
- Kotlin教程学习-数据类型
- wordpress 怎么获取站点标题
- 报告显示,媒体行业已成撞库攻击常见目标
- 直接用自己服务器做图床可以吗_用个人服务器搭建图床
- ssm框架requestmapping找不到_从MVC原理开始手敲一个MVC框架,带你体会当大神的乐趣...
- 在C#中使用反射的简单例子
- C++之priority_queue
- 计算机应用与医学信息基础知识,第一篇医学信息基础知识.PDF
- 创翼软件linux版本,电信创翼客户端下载
- BAT解密:互联网技术发展之路(2)- 业务如何驱动技术发展
- 双硬盘安装win10和linux双系统,双硬盘最初尝试完美安装Windows10 + ubuntu16双系统
- 制作Mind+ Arduino UNO + EMW3080芯片连接阿里云的用户库
- 2.Deep Crossing: Web-Scale Modeling without Manually Crafted Combinatorial Features论文核心解读以及代码实现
- 在前程无忧实习是怎样一个体验
- DesignPattern团队《设计模式在软件开发的应用》讨论会议记录
- 产品版本、软件版本、文档版本定义
- git Please tell me who you are怎么处理解决
- 计算机界面左侧无桌面选项,打印机不能打印 摆脱“无法连接”困扰
- 【C语言】typedef的用法简析