P9577「Cfz Round 1」Dead Cells

发布时间 2023-08-27 10:43:19作者: One_JuRuo

思路

Step1.暴力

考虑到数据范围很小,所以可以暴力模拟操作,赛时直接去想更优的情况,倒是没去想模拟,所以这里就不展开了。

Step2.有点思维难度的做法

首先发现在过程中,只有乘以 \(2\) 和除以 \(2\) 的操作,所以向上取整的情况只会出现在细胞数量为 \(1\) 的情况。

首先讨论 \(a\)\(b\) 的大小情况。

  • \(a>b\),则除以 \(2\) 的次数一定比乘以 \(2\) 的次数多,所以如果没有特殊情况的话,答案一定是 \(1\)。既然我这么说了,这道题就肯定有特殊情况,那么特殊情况是什么呢?如果乘以 \(2\) 的最后一次操作出现在除以 \(2\) 的最后一次操作之后的话,答案会是 \(2\)。那么会有更多的乘以 \(2\) 的操作出现在最后一次除以 \(2\) 的操作之后吗?肯定是没有的,因为 \(a>b\) 所以在两次除法操作中最多有一次乘法操作。

  • \(a<b\),那么每次除以 \(2\) 前,一定乘以了若干次 \(2\),所以最终答案就是 \(2^{\lfloor \frac k a \rfloor - \lfloor \frac k b \rfloor}\)

对于第二种情况,考虑使用快速幂,时间复杂度应该是 \(O(\log ({\lfloor \frac k a \rfloor - \lfloor \frac k b \rfloor}))\)。(蒟蒻不会算时间复杂度,如果错了可以私信或者评论告诉我)

AC 12ms code

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long a,b,k,ans=1;
long long qsm(long long a,long long b)
{
	if(b<=0) return 1;
	long long res=1;
	while(b)
	{
		if(b&1) res=res*a%mod;
		a=a*a%mod,b>>=1;
	}
	return res;
}
int main()
{
	scanf("%lld%lld%lld",&a,&b,&k);
	if(a>b&&k/a*a>k/b*b) printf("2"),exit(0);//特殊情况
	printf("%lld",qsm(2,k/a-k/b));
	return 0;
}