首页 > 其他分享 >AT_abc388_f Dangerous Sugoroku 题解

AT_abc388_f Dangerous Sugoroku 题解

时间:2025-01-12 15:59:39浏览次数:1  
标签:ch return cur int 题解 矩阵 Dangerous abc388 define

太幽默了。

显然可以用矩阵快速幂解决,矩阵里维护距离当前点 \(B\) 以内的所有点可不可达,转移只需分段,在区间内和不在区间内用不同的转移矩阵即可。复杂度 \(O(B^3m\log n)\)。

然后你就 T 了。

此时你很急,你现在应该快点卡常来 AK 这场比赛而不是研究其他的做法,于是我们发现快速幂根本不需要,因为有障碍的区间长度 \(\le B\),然后没障碍的区间对应的矩阵乘到 \(400\) 次方左右就全大于 \(0\) 了。可以直接预处理出矩阵的幂。

然后 \(A = B\) 时肯定是没有上面那条性质的,需要特判。能走到 \(n\) 的条件显然是 \(n \bmod B \equiv 1\) 且没有障碍 \(\bmod B \equiv 1\)。

然后你就 WA 了。

比赛结束我也没调出来,然后我发现一个重要的事情:

\(B\) 可以等于 \(1\)。

就这样寄了。

代码有点乱。

#include<bits/stdc++.h>
typedef long long ll;
#define pii std::pair<ll,ll>
#define mkp std::make_pair
#define fir first
#define sec second
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
	int ch=getchar();
	T f=1;x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x*=f;rd(args...);
}
const int N=25;
ll n;int m,A,B;
std::vector<pii> vec;
struct Matrix{
	int m[N][N],n;
	int* operator[](int x){return m[x];}
	Matrix(int _x=0,int _n=B){
		memset(m,0,sizeof m);n=_n;
		for(int i=1;i<=n;i++)m[i][i]=_x;
	}
	Matrix operator*(Matrix b){
		Matrix c=Matrix();
		for(int k=1;k<=n;k++){
			for(int i=1;i<=n;i++){
				for(int j=1;j<=n;j++){
					(c[i][j]+=m[i][k]*b[k][j]);
				}
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++)c[i][j]=(c[i][j]>0);
		}
		return c;
	}
}bas1,bas2,cur,b2[25],b1[405],a1;
signed main(){
	rd(n,m,A,B);
	if(A==B){
		if(B==1)return printf(m?"No":"Yes"),0;
		int flag=(n%B==1ll);
		for(int i=1;i<=m;i++){
			ll l,r;rd(l,r);
			if(r-l+1>=B)flag=0;
			else{
				for(ll j=l;j<=r;j++)if(j%B==1ll)flag=0;
			}
		}
		puts(flag?"Yes":"No");
		return 0;
	}
	ll now=2;
	for(int i=1;i<=m;i++){
		ll l,r;rd(l,r);
		vec.push_back({now,l-1});
		vec.push_back({l,r});
		if(r-l+1>=B){
			puts("No");
			return 0;
		}
		now=r+1;
	}
	vec.push_back({now,n});
	bas1.n=bas2.n=cur.n=B;
	for(int i=2;i<=B;i++)bas2[i][i-1]=bas1[i][i-1]=1;
	for(int i=1;i<=B-A+1;i++)bas1[i][B]=1;
	cur[1][B]=1;
	b2[1]=bas2;b1[1]=bas1;
	for(int i=2;i<=B;i++)b2[i]=b2[i-1]*bas2;
	for(int i=2;i<=400;i++)b1[i]=b1[i-1]*bas1;
	for(int i=1;i<=B;i++){
		for(int j=1;j<=B;j++)a1[i][j]=1;
	}
	int t=0;
	for(auto [l,r]:vec){
		t^=1;
		if(l>r)continue;
		if(t)cur=cur*(r-l+1<=400?b1[r-l+1]:a1);
		else cur=cur*b2[r-l+1];
	}
	printf(cur[1][B]?"Yes":"No");
	return 0;
}

标签:ch,return,cur,int,题解,矩阵,Dangerous,abc388,define
From: https://www.cnblogs.com/11-twentythree/p/18667006

相关文章

  • Atcoder ABC388F Dangerous Sugoroku 题解 [ 蓝 ] [ 矩阵加速 ] [ 状压矩乘 ] [ 模拟
    DangerousSugoroku:赛时写了矩乘T飞了,受到sunkuangzheng大佬的启发才知道要状压矩乘。暴力矩乘思路直接像过河那样写模拟细节非常多,于是考虑像美食家一样的思路,利用矩阵分段加速。定义\(dp_i\)表示\(i\)能否到达,则有如下转移:\[dp_{i}=\bigvee_{j=i-B}^{i-A}dp_{j}\]......
  • 买房子题解
    【题目要求】问第几年能够买下这套房子。一、建立两个变量,一个表示积攒的钱数,一个表示房价。二、循环20次,判断第i年他能否买下,若能,那么输出i,最后return0。三、在循环外面,输出Impossible。【题解代码】include<bits/stdc++.h>usingnamespacestd;intmain(){double......
  • 整数序列的元素最大跨度值题解
    【题目要求】计算序列的最大跨度值(最大值-最小值)一、求最大值如果a大于最大值,那么最大值就变成a,开始最大值要等于0。二、求最小值如果a小于最小值,那么最小值就变成a,开始最小值要等于1000。【题解代码】include<bits/stdc++.h>usingnamespacestd;intmain(){intn,a,......
  • Atcoder ABC387F Count Arrays 题解 [ 绿 ] [ 基环树 ] [ 树形 dp ] [ 前缀和优化 ]
    CountArrays:一眼秒的计数题。思路显然,把小于等于的条件化为大的向小的连单向边,每个数的入度都是\(1\),就会形成一个基环树森林。那么考虑这个环上能填什么数。因为所有数都小于等于他后面的数,所以所有数都只能相等。这就启发我们在基环树上缩点之后再进行计数。那么当缩完点......
  • 题解:AT_abc388_g [ABC388G] Simultaneous Kagamimochi 2
    鉴于本题解书写时洛谷题面暂无中文翻译,为避免可能的歧义或困惑,先对本题解中的译法进行约定:(顺便吐槽音译怪)英文题面中“mochi”或日文题面中“餅”译为“饼”。英文题面中“kagamimochi”或日文题面中“鏡餅”译为“镜饼”。鉴于本题是C和E的加强版,而我懒得去写那两题的题......
  • AtCoder Beginner Contest 388 (abc388) 赛后复盘
    为什么不会E????A-B模拟即可。C每一个大麻薯可以和所有小于等于自己\(\frac12\)的麻薯结合,二分即可。时间复杂度\(O(n\logn)\)。点击查看代码#include<bits/stdc++.h>#definelllonglong#definei128__int128#definemem(a,b)memset((a),(b),sizeof(a))#def......
  • 2025/1/11 第25场蓝桥入门赛 题解
    A: 哪来的AC  :  题目链接水题:31画#include<iostream>usingnamespacestd;intmain(){//请在此输入您的代码cout<<31;return0;}B: 酒店安排  : 题目链接 思路:从大到小排序,求每两个相邻房间的差值 ,滑动窗口求m-1个差值最小,即为答案要想最......
  • 题解:P1970 [NOIP2013 提高组] 花匠
    闲话本文同步发布在cnblogs。正题容易发现此题要求花必须一高一低摆放。最优化问题,看不出怎么贪心,遂DP。设计状态\(f_{i,0}\)表示当前为上升形势最长花序列,\(f_{i,1}\)表示当前为下降形势最长花序列。状态转移由于需要一高一低,易得:\[f_{i,0}=\begin{cases}......
  • P3247 [HNOI2016] 最小公倍数 题解
    \(\text{P3247[HNOI2016]最小公倍数题解}\)第一眼上去没什么明显的思路。图上问题一般没有什么好的多项式复杂度算法来解决。观察数据范围,注意到\(n,q\le5\times10^4\),是一个典型的根号复杂度算法,于是考虑分块来处理。注意到所求的不一定是简单路径,也就是在不超过所需要的......
  • P10200 花神诞日 题解
    P10200[湖北省选模拟2024]花神诞日题解首先注意到一个集合中两两异或和的最小值就是,排序后相邻两个数异或和的最小值。证明可以考虑放到01-Trie上,从高往低位建树,求一个数与之异或的最小值,就是使高位相同位数尽可能多,则就是01-Trie上的前一个叶子或后一个叶子。由此,我们......