Atcoder ABC388F Dangerous Sugoroku 题解 [ 蓝 ] [ 矩阵加速 ] [ 状压矩乘 ] [ 模拟 ]
Dangerous Sugoroku:赛时写了矩乘 T 飞了,受到 sunkuangzheng 大佬的启发才知道要状压矩乘。
暴力矩乘思路
直接像过河那样写模拟细节非常多,于是考虑像美食家一样的思路,利用矩阵分段加速。
定义 \(dp_i\) 表示 \(i\) 能否到达,则有如下转移:
\]
因为 \(A,B\le 20\),所以可用状态非常少,就可以用矩阵优化了。
那么很显然就把段拆一下,然后直接跑矩乘就好了。这个做法甚至连 \(m=0,l_i-1=r_{i-1}\) 的细节都不用判。
代码如下,如果你真这么写了,会收获 TLE 和 WA 的好成绩!
下面这份暴力中 \(dp_i\) 表示 \(dp_i\) 的方案数,所以转移有所不同,本质还是和上面一样的。只要 \(dp_i>0\) 就能到达。
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
struct mat{
ull a[25][25];
mat(){memset(a,0,sizeof(a));}
mat operator*(const mat &x)const{
mat res;
for(int i=0;i<=20;i++)
{
for(int k=0;k<=20;k++)
{
ull l=a[i][k];
for(int j=0;j<=20;j++)
{
res.a[i][j]=(res.a[i][j]+l*x.a[k][j]);
}
}
}
return res;
}
}s,dp1,dp2;
mat qpow(mat x,ll k)
{
mat res;
for(int i=0;i<=20;i++)res.a[i][i]=1;
while(k>0)
{
if(k&1)res=res*x;
x=x*x;
k>>=1;
}
return res;
}
ll n,m,a,b,l[200005],r[200005];
int main()
{
//freopen("sample.in","r",stdin);
//freopen("sample.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>a>>b;
s.a[1][20]=1;
for(int i=1;i<=19;i++)dp1.a[i+1][i]=dp2.a[i+1][i]=1;
for(int i=20-a+1;i>=20-b+1;i--)dp1.a[i][20]=1;
r[0]=1;
for(int i=1;i<=m;i++)
{
cin>>l[i]>>r[i];
if(r[i]-l[i]+1>=21||l[i]==1)
{
cout<<"No";
return 0;
}
if(l[i]-r[i-1]-1>0)s=s*qpow(dp1,l[i]-r[i-1]-1);
if(r[i]-l[i]+1>0)s=s*qpow(dp2,r[i]-l[i]+1);
}
if(n+1-r[m]-1>0)s=s*qpow(dp1,n+1-r[m]-1);
if(s.a[1][20])cout<<"Yes";
else cout<<"No";
return 0;
}
原因是复杂度为 \(O(m\times 20^3 \log n)\),常数又大,无法通过。
优化矩乘
因为状态中只有 \(0\) 和 \(1\),每行每列的数又只有 \(20\) 个,考虑用状压与位运算去掉一个 \(20\)。
我们先看暴力的矩乘代码,再来考虑如何优化它。
struct mat{
ull a[25][25];
mat(){memset(a,0,sizeof(a));}
mat operator*(const mat &x)const{
mat res;
for(int i=0;i<=20;i++)
{
for(int k=0;k<=20;k++)
{
for(int j=0;j<=20;j++)
{
res.a[i][j]=(res.a[i][j]|(a[i][k]&x.a[k][j]));
}
}
}
return res;
}
}
可以发现,当 \(a_{i,k}=1\) 时,\(res_{i,j}\) 取决于 \(x_{i,j}\) 是否为 \(1\)。
因此,就可以省去循环 \(j\),当 \(a_{i,k}=1\) 时,直接让 \(res_i \gets res_i \vee x_k\) 即可。
时间复杂度 \(O(m\times 20^2 \log n)\),可以通过。
代码如下:
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
struct mat{
ull a[25];
mat(){memset(a,0,sizeof(a));}
mat operator*(const mat &x)const{
mat res;
for(int i=0;i<=20;i++)
{
for(int k=0;k<=20;k++)
{
if((a[i]>>k)&1)res.a[i]=(res.a[i]|x.a[k]);
}
}
return res;
}
}s,dp1,dp2;
mat qpow(mat x,ll k)
{
mat res;
for(int i=0;i<=20;i++)res.a[i]=(1<<i);
while(k>0)
{
if(k&1)res=res*x;
x=x*x;
k>>=1;
}
return res;
}
ll n,m,a,b,l[200005],r[200005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>a>>b;
s.a[1]=(1<<20);
for(int i=1;i<=19;i++)dp1.a[i+1]=dp2.a[i+1]=(1<<i);
for(int i=20-a+1;i>=20-b+1;i--)dp1.a[i]|=(1<<20);
r[0]=1;
for(int i=1;i<=m;i++)
{
cin>>l[i]>>r[i];
if(r[i]-l[i]+1>=21||l[i]==1)
{
cout<<"No";
return 0;
}
if(l[i]-r[i-1]-1>0)s=s*qpow(dp1,l[i]-r[i-1]-1);
if(r[i]-l[i]+1>0)s=s*qpow(dp2,r[i]-l[i]+1);
}
if(n+1-r[m]-1>0)s=s*qpow(dp1,n+1-r[m]-1);
if((s.a[1]>>20)&1)cout<<"Yes";
else cout<<"No";
return 0;
}
Atcoder ABC388F Dangerous Sugoroku 题解 [ 蓝 ] [ 矩阵加速 ] [ 状压矩乘 ] [ 模拟 ]的更多相关文章
- 【题解】P3959 宝藏 - 状压dp / dfs剪枝
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝 ...
- Bzoj 3813 奇数国 题解 数论+线段树+状压
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 748 Solved: 425[Submit][Status][Discuss] ...
- NOIp2016 D2T3 愤怒的小鸟【搜索】(网上题解正解是状压)
题目传送门 没啥别的想法,感觉就是搜索,经过原点的抛物线已知两个点就可以求出解析式,在还没有被打下来的两个猪之间随意配对,确定解析式之后标记在这个抛物线下被打下来的猪. 猪也可以单独用一个抛物线打下来 ...
- 【题解】P2831 愤怒的小鸟 - 状压dp
P2831愤怒的小鸟 题目描述 \(Kiana\) 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 \((0,0)\) 处,每次 \(Kiana\) 可以 ...
- 洛谷 P1939 矩阵加速(数列)
题意简述 \(a[1]=a[2]=a[3]=1\) \(a[x]=a[x−3]+a[x−1](x>3)\) 求a数列的第n项对1000000007取余的值. 题解思路 矩阵加速 设\[ F=\b ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- BZOJ2004:[HNOI2010]Bus 公交线路(状压DP,矩阵乘法)
Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定 ...
- 【KMP】【矩阵加速】【递推】洛谷 P3193 [HNOI2008]GT考试 题解
看出来矩阵加速也没看出来KMP…… 题目描述 阿申准备报名参加 GT 考试,准考证号为\(N\)位数\(X_1,X_2…X_n(0\le X_i\le9)\),他不希望准考证号上出现不吉利的数 ...
- 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)
洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...
- [模板][题解][Luogu1939]矩阵乘法加速递推(详解)
题目传送门 题目大意:计算数列a的第n项,其中: \[a[1] = a[2] = a[3] = 1\] \[a[i] = a[i-3] + a[i - 1]\] \[(n ≤ 2 \times 10^ ...
随机推荐
- highcharts在vue中的应用
1.安装命令 npm install highcharts --save 2.在页面中按需引入 import Highcharts from 'highcharts/highstock'; impor ...
- 从零开始学java(第二天)
------------恢复内容开始------------ 今天是学习了一些基础的知识 1.注释 //行注释 /*多行注释*/ /**文档注释*/ 2.标识符和关键字 标识符就是名字,类名方法名变量 ...
- c# is 和 as 浅看重制版
前言 当年写的比较差:https://www.cnblogs.com/aoximin/p/12965408.html,所以特来重新写一遍. 正文 首先为什么会出现is 和 as 呢? 因为是为了有需要 ...
- API开发与管理规范v1.0
1. 协议规范 为了确保不同业务系统之间以及前后端的的数据交互的快捷性,通讯协议统一约定如下: 对内调用的API接口统一使用 HTTP协议 对外互联网发布的API建议使用HTTPS协议也可以使用HTT ...
- mysql忘记密码的终极解决方案(docker-compose)
MYSQL8的安全性能有所提高,装好后,各种不适应,需要各种调试. 1. 首先,root密码忘记或是更改,操作步骤: vi mysql/config/my.cnf 在[mysqld]的段中加上一句:s ...
- COSBrowser 文件对比——更实用的文件管理功能
我们在使用 COSBrowser 来管理腾讯云存储的文件时,目前我们大家所熟知的上传/下载方式,主要有以下三种: 通过点击按钮上传/下载 通过拖拽的形式进行上传/下载 通过 URL 链接进行上传/下载 ...
- 【金TECH频道】企业架构转型组合拳来袭,助力金融机构一臂之力
当前,数字化转型已经成为时代共性课题在政策和技术的双重指引下金融机构逐渐走向差异化竞争的格局面对转型阵痛以契合.明晰的战略规划及企业架构调整来辅助业务变革成为助力企业数字化转型的有效路径金融机构也纷纷 ...
- Consul health check pass by Spring security filter
https://stackoverflow.com/questions/35079930/consul-health-check-pass-by-spring-security-filter By d ...
- dubbo(一)spring schema拓展技术
https://blog.csdn.net/java_zldz_xuws/article/details/84648398 在阐述dubbo原理之前,我先介绍一下dubbo与spring怎么糅合在一块 ...
- MySQL语句判断数据库数据重复情况,新增、删除、不变。
判断 7月8月两个月数据对比情况,新增.删除(离职).重复. 根据manager_name,gg_name,employer,department,historical_office判断出是否重复数据 ...