【题解】ARC 128

挺离谱的。

A~D 都不是很难,可惜 D 赛后 10 min 就切掉了。

今晚没有打牛客 (我还睡了一觉 qwq)

A - Gold and Silver

比较考验阅读理解能力。

注意换和购入不能同时发生 只能 either 或 neither

所以最简单的方法就是 ^1 。

判断如果 a[i]>a[i+1] 则证明应该第 i 天全部换成银币,第二天再全部换回来(即换成金币),相当于 vis[i]^=1 且 vis[i+1]^=1 。(如果你交换 a[i] 和 a[i+1] 可能会 wa 掉,因为题目说了要保证最后剩的是金币且最多)

#include<bits/stdc++.h>
#define ll long long
#define db double
#define inf 0x3f3f3f3f
using namespace std;
const int N=2e5+5;
int n,a[N],vis[N];
int main() {
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<n;i++) {
		if(a[i]>a[i+1]) {
			vis[i]^=1,vis[i+1]^=1;
		}
	}
	for(int i=1;i<=n;i++) printf("%d ",vis[i]);
}

B - Balls of Three Colors

枚举全排列 a 0 , a 1 , a 2 {a_0,a_1,a_2} a0,a1,a2

手玩一下可以发现 ∣ a 0 − a 1 ∣ |a_0-a_1| a0a1 必须是 3 3 3 的倍数,同时操作次数恰好为 m a x ( a 0 , a 1 ) max(a_0,a_1) max(a0,a1)

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int n,a[3],res;
int main() {
	int T; cin>>T;
	while(T--) {
		cin>>a[0]>>a[1]>>a[2];
		sort(a,a+3);
		res=inf;
		do{
			if(abs(a[0]-a[1])%3==0) {
				res=min(res,max(a[0],a[1]));
			}
		}while(next_permutation(a,a+3));
		if(res==inf) printf("-1\n");
		else printf("%d\n",res);
	}
}

C - Max Dot

这题稍微要想一下 (但是突破了应该实现不难)

我们考虑当前 max ⁡ ( a 1 , . . . , a n ) \max(a_1,...,a_n) max(a1,...,an) 的位置。记最大值的位置为 i 。

如果 i = n i=n i=n 的话就直接令 x i x_i xi 取最大值,否则不难发现 x i = x i + 1 x_i=x_{i+1} xi=xi+1。此时定义新贡献为 一段区间的和除以区间长度。可以划归到长度为 n − 1 n-1 n1 的问题。若 n = 1 n=1 n=1则这个整体都赋 S l 1 \frac{S}{l_1} l1S 即可。

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int n,a[3],res;
int main() {
	int T; cin>>T;
	while(T--) {
		cin>>a[0]>>a[1]>>a[2];
		sort(a,a+3);
		res=inf;
		do{
			if(abs(a[0]-a[1])%3==0) {
				res=min(res,max(a[0],a[1]));
			}
		}while(next_permutation(a,a+3));
		if(res==inf) printf("-1\n");
		else printf("%d\n",res);
	}
}

D - Neq Neq

基本思路:固定右端点 i i i ,找满足条件的合法的前继 j < i j<i j<i

然后找到 [l,r] 能被消除的充要条件:任意两个点的颜色不相同且颜色个数 >=3 (或者长度 <=3)

这里的 trick 是用不等式来夹逼范围。即分为 j<=i-3 和 i-2<=j<=n-1 两种情况(因为 n=2 或 n=3 时不同颜色数 <=2 也是合法转移)

可以理解成分段函数。

特判贼 jb 恶心 。

#include<bits/stdc++.h>
#define ll long long
#define db double
#define inf 0x3f3f3f3f
using namespace std;
const int N=2e5+5;
const int mod=998244353;
int n,f[N],a[N];
ll dp[N],sum[N];
ll qry(int l,int r) {
	if(l>r) return 0;
	return (sum[r]-sum[l-1]+mod)%mod;
}
int main() {
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int j=1;
	f[1]=sum[1]=dp[1]=1;
	for(int i=2;i<=n;i++) {
		f[i]=a[i]==a[i-2]?f[i-2]:i;
		if(a[i]==a[i-1]) {
			j=i;
			dp[i]=dp[i-1];
			sum[i]=(sum[i-1]+dp[i])%mod;
			continue;
		}
		dp[i]=(qry(j,min(max(f[i],f[i-1])-2,i-3))+qry(max(j,i-2),i-1))%mod;
		sum[i]=(sum[i-1]+dp[i])%mod;
	}
	cout<<dp[n];
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值