原文链接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;
}

  

BZOJ3583 杰杰的女性朋友 矩阵的更多相关文章

  1. [BZOJ3583]杰杰的女性朋友(矩阵快速幂)

    杰杰的女性朋友 时间限制:10s      空间限制:256MB 题目描述 杰杰是魔法界的一名传奇人物.他对魔法具有深刻的洞察力,惊人的领悟力,以及令人叹为观止的创造力.自从他从事魔法竞赛以来,短短几 ...

  2. BZOJ3583 : 杰杰的女性朋友

    将$I$转置,设$G=OI$,则$ans=G^0+G^1+...+G^d$. 注意到$G^d=O(IO)^{d-1}I$,而$IO$是大小为$k\times k$的矩阵,可以通过倍增在$O(k^3\l ...

  3. bzoj3583: 杰杰的女性朋友 && 4362: Graph

    Description 给出一张n个点的有向图G(V,E).对于任意两个点u,v(u可以等于v),u向v的连边数为: ∑OUT(u,i) * IN(v,i),其中1<=i<=K 其中k和数 ...

  4. bzoj3583 杰杰的女性朋友 || bzoj4362 Graph

    http://210.33.19.103/problem/2174 很显然是矩阵快速幂的题,设有in和ou矩阵,设in矩阵的转置为in' 显然可以直接暴力求出任意两点间走一步路径条数,然后求其d次幂, ...

  5. cojs QAQ的矩阵 题解报告

    题目描述非常的清晰 首先我们考虑(A*B)^m的求法,这个部分可以参考BZOJ 杰杰的女性朋友 我们不难发现(A*B)^m=A*(B*A)^(m-1)*B A*B是n*n的矩阵,而B*A是k*k的矩阵 ...

  6. 复旦大学EWP菁英女性课程(复旦卓越女性课程改版后第一期) _复旦大学、女性课程、高级研修班、心理学、EWP_培训通课程

    复旦大学EWP菁英女性课程(复旦卓越女性课程改版后第一期) _复旦大学.女性课程.高级研修班.心理学.EWP_培训通课程 复旦大学EWP菁英女性课程(复旦卓越女性课程改版后第一期)    学      ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. qbxt五一数学Day1

    目录 I. 基础知识 1. 带余除法(小学) 1. 定义 2. 性质 2. 最大公约数(gcd)/ 最小公倍数(lcm) 1. 定义 2. 性质 3. 高精度 II. 矩阵及其应用 1. 定义 2. ...

  9. DOM实战

    作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正 视频来源:https://www.bil ...

随机推荐

  1. Scientific Toolworks Understand

    Scientific Toolworks Understand是一款定位于代码阅读的软件.界面用Qt开发的. 软件特性: 1.支持多语言:Ada, C, C++, C#, Java, FORTRAN, ...

  2. Oracle11g 体系结构

    一:Oracle11g 体系结构 二:逻辑储存结构 二.1:数据块(data blocks) ----通过 v$parameter数据字典来查询oracle标准数据块的大小. SYS@orcl> ...

  3. Swift 通过字符串创建控制器

    由于Swift 中新增了一个命名空间(在同一个命名空间中的文件可以直接访问而不用引入头文件)的概念 所以通过字符串创建控制器需要带上命名空间 1 首先为Bundle 写一个分类  获取命名空间 ext ...

  4. ionic3 点击input 弹出白色遮罩 遮挡上部内容

    在Manifest中的activity里设置android:windowSoftInputMode为adjustPan,默认为adjustResize,当前窗口的内容将自动移动以便当前焦点从不被键盘覆 ...

  5. jq插件模板

    !(function($,window, document, undefined){ function Plugin(ele,options){ //默认参数设置 this.defaults={ pa ...

  6. laravel 视图

    在实际开发中,除了 API 路由返回指定格式数据对象外,大部分 Web 路由返回的都是视图,以便实现更加复杂的页面交互,我们在前面已经看到过了视图的定义方式: return view('以.分隔的视图 ...

  7. cf round546 cde

    第一题会卡一下同时用set和cin.. 其他的注意下矩阵对角线下标的应用即可 #include<bits/stdc++.h> using namespace std; #define ma ...

  8. Appium 如何模拟按键

    from appium.webdriver import Remote driver.keyevent(4) python中点击返回键是这样写的 附录 keycode 电话键 KEYCODE_CALL ...

  9. python操作注册表

    #注册表操作 # -*- coding: utf-8 -*- import win32api import win32con #打开注册表:传主键化值,子键值,操作方法(win32con.KEY_AL ...

  10. 关于The specified Android SDK Build Tools version (26.0.2) is ignored, as it is below the minimum...

    今天将项目迁移到另一台笔记本,进行build出现以下问题,导致build失败 The specified Android SDK Build Tools version (26.0.2) is ign ...