CF2070C 学习笔记

二分太久没碰了,找一道题练练手。

谈谈做法

注意到题目中有这样一句话:

最终涂色的总惩罚值定义为所有错误颜色单元格的惩罚值的最大值

如果没有错误颜色的单元格,总惩罚值为 0。

求可以达到的最小总惩罚值是多少?

求最大的最小的问题,我们考虑用二分解决。

谈谈细则

二分这种事情相信大家都不陌生,要说它难也就难在填 check 函数,考虑贪心来检查 \(mid\) 是否可行。

具体怎么实现呢?我们可以记录上一个字符为 \(pre\),在 \(a_i>mid\),且 \(s_{i-1}=B\)\(pre\)\(s_{i-1}\) 不相等时对计数器进行累加,并更新 \(pre\) 的值。

谈谈实现

直接上代码。

/**********************************************************
 * Author        : dingziyang888
 * Website       : https://www.luogu.com.cn/problem/CF2070C
 * Created Time  : 2025/12/30 22:21
 * FileName      : CF2070C.cpp
 * Warning!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * 1.MLE?
 * 2.array size enough?
 * 3.long long?
 * 4.overflow long long?
 * 5.multiple task cleaned?
 * 6.freopen?
 * 7.TLE?
 * *******************************************************/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iterator>
#include <map>
#include <unordered_map>
#include <queue>
#include <string>
#include <cstring>
#include <set>
#include <bitset>
#include <unordered_set>
#include <vector>
#include <deque>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <list>
#include <array>
#include <iterator>
#include <cmath>
#include <new>
#include <random>
#include <cfloat>
#include <cstdlib>
#include <climits>
#include <numeric>
#include <complex>
#include <ctime>
#include <chrono>
#include <thread>
#include <mutex>
#include <future>
#include <exception>
#include <stdexcept>
#include <cstdint>
#include <cassert>
#include <stack>
#include <cctype>
#define DEBUG
#define Ofile(s) freopen(s".in", "r", stdin), freopen (s".out", "w", stdout)
#define Cfile(s) fclose(stdin), fclose(stdout)
#define fast ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
using namespace std;

using ll = long long;
using ull = unsigned long long;
using lb = long double;

constexpr int mod = 998244353;
constexpr int maxn = 300005;

int t, n, k, ans;

int a[maxn];

string s;

bool check(int mid){
	int sum = 0;
	char pre = 'R';
	for (int i = 1; i <= n; i++)
		if (a[i] > mid){
			if (s[i - 1] == 'B' and pre != s[i - 1])	++sum;
			pre = s[i - 1];
		}
	return sum <= k;
}

int main() {
	cin >> t;
	while (t--){
		cin >> n >> k >> s;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		int l = 0, r = 1e9;
		ans = 0;
		while (l <= r){
			int mid = (l + r) >> 1;
			if (check(mid)) ans = mid, r = mid - 1;
			else l = mid + 1;
		}
		cout << ans << endl;
	}
	return 0;
}
posted @ 2026-02-02 19:13  constexpr_ll  阅读(0)  评论(0)    收藏  举报