CF781D Axel and Marston in Bitland [倍增 矩阵乘法 bitset]
好开心第一次补$F$题虽然是$Div.2$
题意:
一个有向图,每条边是$0$或$1$,要求按如下规则构造一个序列然后走:
第一个是$0$,每次复制当前序列,取反后贴在后面
如:$0,01,0110,01101001,...$
注意走的是$01101001$而不是$0 01 0110 01101001$
一开始读错题了然后郁闷了好久....
求最多走几次,如果$> 1e18$就输出$-1$
(1 ≤ n ≤ 500, 0 ≤ m ≤ 2n^2)
看到了左下角的$matrices$标签就开始往矩阵乘法想
图上的路径问题可以转化成邻接矩阵的矩阵乘法
我们如果用矩阵乘法预处理出按照序列走了几次之后的矩阵貌似可做啊
然后想不太明白了就参考了一下别人的代码
$g[0/1][i]$表示正$0$反$1$,走了$2^i$步之后的矩阵
显然存在递推关系
$g[0][i]=g[0][i-1]*g[1][i-1];\ g[1][i]=g[1][i-1]*g[0][i-1];$
然后用倍增的思想从大到小选择看看能不能走这个矩阵就行了
用$a[i]$表示当前能否走到$i$,$a[i]==1$就可以走到当前矩阵所有$i$能走到的点啦
注意这里的矩阵$c[i][j]$表示能否从$i$走到$j$
然后可以用$bitset$优化,矩阵乘法可以省掉一层循环
不知道为什么常数超小......374ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <bitset>
using namespace std;
typedef long long ll;
const int N=,M=;
const ll INF=1e18;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,u,v,p;
struct Matrix{
bitset<N> a[N];
bitset<N>& operator [](int x){return a[x];}
void ini(){for(int i=;i<=n;i++) a[i].reset();}
}g[][M];
Matrix operator *(Matrix a,Matrix b){
Matrix re;
for(int i=;i<=n;i++)
for(int k=;k<=n;k++) if(a[i][k])
re[i]|=b[k];
return re;
}
bitset<N> a,t;
ll ans;
int main(){
//freopen("in","r",stdin);
n=read();m=read();
for(int i=;i<=m;i++){
u=read();v=read();p=read();
g[p][][u][v]=;
}
for(int i=;i<M;i++){
g[][i]=g[][i-]*g[][i-];
g[][i]=g[][i-]*g[][i-];
}
int s=;a[]=;
for(int now=M-;now>=;now--){
t.reset();
for(int i=;i<=n;i++)
if(a[i]==) t|=g[s][now][i];
if(t.count()){
a=t;
s^=;
ans+=(1LL<<now);
}
if(ans>INF) {puts("-1");return ;}
}
cout<<ans;
}
CF781D Axel and Marston in Bitland [倍增 矩阵乘法 bitset]的更多相关文章
- 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法
题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...
- 倍增&矩阵乘法 专题复习
倍增&矩阵乘法 专题复习 PreWords 这两个基础算法我就不多说啦,但是还是要介绍一下" 广义矩阵 "乘法 其实就是把矩阵换成取\(max\),然后都一样... 据神仙 ...
- Codeforces 781D Axel and Marston in Bitland 矩阵 bitset
原文链接https://www.cnblogs.com/zhouzhendong/p/CF781D.html 题目传送门 - CF781D 题意 有一个 n 个点的图,有 m 条有向边,边有两种类型: ...
- 4.28 省选模拟赛 负环 倍增 矩阵乘法 dp
容易想到 这个环一定是简单环. 考虑如果是复杂环 那么显然对于其中的第一个简单环来说 要么其权值为负 如果为正没必要走一圈 走一部分即可. 对于前者 显然可以找到更小的 对于第二部分是递归定义的. 综 ...
- 【POJ3613】Cow Relays 离散化+倍增+矩阵乘法
题目大意:给定一个 N 个顶点,M 条边的无向图,求从起点到终点恰好经过 K 个点的最短路. 题解:设 \(d[1][i][j]\) 表示恰好经过一条边 i,j 两点的最短路,那么有 \(d[r+m] ...
- Codeforces 781D Axel and Marston in Bitland
题目链接:http://codeforces.com/contest/781/problem/D ${F[i][j][k][0,1]}$表示是否存在从${i-->j}$的路径走了${2^{k}} ...
- Axel and Marston in Bitland CodeForces - 782F (bitset优化)
题目链接 $dp[0/1][i][x][y]$表示起始边为0/1, 走$2^i$ 步, 是否能从$x$走到$y$ 则有转移方程 $dp[z][i][x][y]\mid=dp[z][i-1][x][k] ...
- codeforces781D Axel and Marston in Bitland
题目链接:codeforces781D 正解:$bitset$+状压$DP$ 解题报告: 考虑用$f[t][0.1][i][j]$表示从$i$出发走了$2^t$步之后走到了$j$,且第一步是走的$0$ ...
- CodeForces 781D Axel and Marston in Bitland DP
题意: 有一个\(n\)个点\(m\)条边的无向图,边有两种类型,分别用\(0\)和\(1\)标识 因此图中的任意一条路径都对应一个\(01\)字符串 定义一个无限长的字符串\(s\): 开始令\(s ...
随机推荐
- Java入门篇(三)——Java流程控制
前两篇已经了解了Java语言基础,本篇开始Java的流程控制.流程控制对任何一门编程语言都是至关重要的,它提供了控制程序步骤的基本手段. 一.复合语句 Java语言的复合语句是以整个块区为单位的语句, ...
- Qt布局操作
Qt界面布局是用来界面上控件排序的,例如对齐.自适应分辨率等都要用到布局. Qt界面布局跟Visual Studio系列完全不一样,VS系列的操作很简单,一般情况下,很快就能入手了,但比较死板(特别是 ...
- 整理关于web项目如何防止CSRF和XSS攻击的方法
1 了解CSRF的定义 CSRF(Cross-site request forgery)跨站请求伪造,也被称为"One Click Attack"或者Session Riding, ...
- DEDECMS系统安全篇之移data目录到Web根目录以外听语音
http://jingyan.baidu.com/article/ad310e80aeb0971849f49e8e.html 主要三个步骤: 1./include/common.inc.php 2.还 ...
- ASP.NET Core下发布网站
一.windows下发布到IIS 1.前奏:IIS上的准备 (1)IIS 必须安装AspNetCoreModule 模块 下载地址:(DotNetCore.2.0.3-WindowsHosting-a ...
- OOAD之策略模式(1)
在引入策略模式之前.先用一个小项目解释为什么要有策略模式.这是一个模拟鸭子的小游戏.最开始需求为,所有的鸭子都会叫以及都会游泳且叫声游泳姿势都一样.因此我们用原始OO的思维去编写代码时很容易做到 pu ...
- Hyperledger Fabric Read-Write set semantics——读写集
Read-Write set semantics(读写集) 本文讨论了关于读写集当前实现的细节. Transaction simulation and read-write set(事务模拟和读写集) ...
- mmap 测试的一些坑
最近遇到一个mmap的问题,然后为了测试该问题,写了如下测试代码: #include <sys/mman.h> #include <sys/stat.h> #include & ...
- Servlet--转发和重定向
Servlet的跳转有2种,一种是转发,一种是重定向. 重定向: <strong><span style="font-size:14px;"></sp ...
- linkin大话面向对象--构造器详解
对象的产生格式:类名称 对象名 = new 类名称(); 因为有(),所以是方法,实际上它就是构造方法,并且是非私有的构造方法.如:CellPhone cp = new CellPhone( ...