CF R872 div.2

C

 首先发现第三种操作要去个重,剩下的 \(x_i\) 的个数和就是最劣答案,现在思考如何用前两种操作使答案变优。
不难发现可以枚举每一个 \(x_i\),再考虑 \(1 \sim (x_i-1)\)\((x_i+1) \sim m\) 中有多少空位,空位即是总位置数减区间内\(x_i\) 个数。
空位和操作 \(1,2\)\(min\),即为可增加的答案。时间复杂度 \(O(nlogn)\),需要排序。
思路还是好想,代码恶心,写了好久。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N];
void solve(){
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	vector<int> b;
	int left = 0, right = 0;
	for(int i = 1; i <= n; i++){
		if(a[i] == -1) left ++;
		if(a[i] == -2) right ++;
		if(a[i] > 0) b.push_back(a[i]);
	}
	sort(b.begin(), b.end());
	b.erase(unique(b.begin(), b.end()), b.end());
	int nn = b.size();
	int ans = max(min(left + nn, m), min(right + nn, m)), cnt = 1;
	for(auto t : b){
		int l = t - cnt;
		int r = m - t - (nn - cnt);
		ans = max(ans, nn + min(l, left) + min(r, right));
		cnt ++;
	}
	cout << ans << endl;
}
int main(){
	int T; cin >> T;
	while(T --)
		solve();
	return 0;
}

D

posted @ 2023-05-18 10:09  P32sx  阅读(29)  评论(0)    收藏  举报