CF2189

A. Table with Numbers

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 108;
int a[NN];
void solve(){
	int n,h,l;
	cin >> n >> h >> l;
	if(h > l) swap(h,l);
	for(int i = 1; i <= n; ++i) cin >> a[i];
	sort(a+1,a+1+n);
	int pos = upper_bound(a+1,a+1+n,h) - a,pos2 = upper_bound(a+1,a+1+n,l) - a;
	int lw = pos - 1, up = pos2 - pos;
	if(up > lw) cout << lw << '\n';
	else cout << (up+lw) / 2 << '\n';
}
int main(){
	ios::sync_with_stdio(false),cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		solve();
	}
} 

B. The Curse of the Frog

tag: 贪心

我们首先把所有免费额度全部跳完 \(\sum a_i \times (b_i-1)\)

之后便是每次跳跃都会花费一个额度,向前跳 \(w_i = a_i \times b_i - c_i\)

所以每次贪心选择 \(w_i\) 最大的进行跳跃即可

code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 2e18;
void solve(){
	ll n,x;
	cin >> n >> x;
	ll now = 0,maxn = -INF;
	for(int i = 1; i <= n; ++i){
		ll a,b,c;
		cin >> a >> b >> c;
		now += a * (b-1);
		maxn = max(a * b - c, maxn);
	}
	if(now >= x){
		cout << "0\n";
		return;
	}
	else{
		if(maxn <= 0) cout << "-1\n";
		else{
			cout << (x - now + maxn - 1) / maxn << "\n";
		}
	}
}
int main()
{
	ios::sync_with_stdio(false),cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}

C1. XOR Convenience (Easy Version)

直接让 \(a_n = 1\) 即可,剩下的 \(a_i = i \oplus 1(2\leq i \leq n-1)\)

code
#include<bits/stdc++.h>
using namespace std;
void solve(){
	int n;
	cin >> n;
	if(n == 1){
		cout << "1\n";
	}
	else if(n % 2 == 0){
		cout << n << " ";
		for(int i = 2; i < n; ++i){
			cout << (i ^ 1) << " ";
		}
		cout << "1\n";
	}
	else{
		cout << n-1 << " ";
		for(int i = 2; i < n; ++i){
			cout << (i ^ 1) << " ";
		}
		cout << "1\n"; 
	}
}
int main()
{
	ios::sync_with_stdio(false),cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		solve();
	}
	return 0;
}

C2. XOR-convenience (Hard Version)

如果 \(n\) 为奇数,那么 \(f_{n-1} = 1,\ f_1 = n-1,\ f_n = n,\ f_i = i \oplus 1\)

\(n\)\(2^k\) 无解

如果 \(n\) 为偶数,C1 的基础上交换 \(a_1, a_{lowbit(n)}\) 即可

code
#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
int a[NN];
inline int lowbit(int x){return x & (-x);}
int main()
{
	ios::sync_with_stdio(false),cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		int n;
		cin >> n;
		int m = n; 
		while((m&1) == 0){
			m >>= 1;
		}
		if(m == 1 && n != 1) cout << -1 << '\n';
		else if(n == 1){
			cout << "1\n";
			continue;
		}
		else if(n % 2 == 0){
			for(int i = 2; i <= n-1; ++i){
				a[i] = i ^ 1;
			}
			a[1] = n;
			a[n] = 1;
			swap(a[1],a[lowbit(n)]);
			for(int i = 1; i <= n; ++i) cout << a[i] << " ";
			cout << "\n";
		}
		else{
			cout << n - 1 << " ";
			for(int i = 2; i <= n-2; ++i){
				cout << (i ^ 1) << " ";
			}
			cout << "1 " << n << '\n';
		}
	}
	return 0;
}

D1. Little String (Easy Version)

tag: 计数 mex 排列

排列的区间 \(mex\) 等于其前缀和后缀的最小值

显然 \(s_1 = s_n = 1\),因为只选 \(0\)\(mex\)\(1\),什么都选的 \(mex\)\(n\)

之后我们从大到小放入每一个数

  • \(s_i == 0\),那么就不能放在两端,得放中间 \(ans *= i-1\)
  • \(s_i == 1\),那么就需要放在两端,\(ans *= 2\)
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int NN = 2e5 + 8;
void solve(){
	ll n,c;
	cin >> n >> c;
	ll ans = 1, ans2 = 1;
	string s;
	cin >> s;
	s = ' ' + s;
	if(s[1] == '0' || s[n] == '0') return cout << "-1\n", void(0);
	for(ll i = n-1; i >= 1; --i){
		if(s[i] == '1') ans = ans * 2 % MOD, ans2 = ans2 * 2 % c;
		else{
			if(i-1 == 0) return cout << "-1\n", void(0);
			ans = ans * (i - 1) % MOD;
			ans2 = ans2 * (i - 1) % c;
		}
	}
	if(ans2 == 0) return cout << "-1\n", void(0);
	cout << ans << '\n';
	return;
}
int main(){
	ios::sync_with_stdio(false),cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		solve();
	}
} 

D2. Little String (Hard Version)

tag: 因数 贪心

首先 0 和 1 的贡献是固定的

我们现在主要减少问号的贡献

我们知道,将一个问号变成 \(1\)\(2\) 的贡献

将一个问号变成 \(0\)\(i-1\) 的贡献

\(i-1\) 为偶数,显然将这个问号变成 \(1\) 无论如何都更划算

若为奇数且 \(i-1 \neq 1\),则待定

我们对于不能是 \(c\) 的倍数这个条件,维护 \(c\) 和当前答案的 \(gcd\)

若做完以上操作后,\(c\) 不是 \(2\) 的次幂,那么待定的所有位都给出 \(2\) 的贡献

否则,贪心地让 \(i-1\) 更大的问号贡献 \(2\),直到 \(gcd = 2\)

code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int NN = 2e5 + 8;
inline int gcd(int x,int y){
	return x == 0 ? y : gcd(y % x, x);
}
vector<int> num;
int check(int x){
	int cnt = 0;
	while(!(x & 1)){
		x >>= 1;
		++cnt; 
	}
	if(x == 1) return cnt;
	else return -1;
}
void solve(){
	ll n,c;
	cin >> n >> c;
	ll ans = 1;
	string s;
	cin >> s;
	s = ' ' + s;
	if(s[1] == '0' || s[n] == '0') return cout << "-1\n", void(0);
	s[1] = s[n] = '1';
	num.clear();
	for(ll i = n-1; i >= 1; --i){
		if(s[i] == '1') ans = ans * 2 % MOD, c = c / gcd(c, 2);
		else if(s[i] == '0'){
			ans = ans * (i - 1) % MOD;
			c = c / gcd(c, i-1);
		}
		else{
			if(i % 2 == 1) c = c / gcd(c,2), ans = ans * 2 % MOD;
			else if(i-1 != 1) num.push_back(i-1);
		}
	}
	if(c == 1) return cout << "-1\n", void(0);
	ll numc = check(c);
	if(numc >= 0){
		for(int i = 0; i < min(numc - 1,(long long)num.size()); ++i){
			ans = ans * 2 % MOD;
		}
		for(int i = numc - 1; i < num.size(); ++i){
			ans = ans * num[i] % MOD;
		}
		cout << ans << '\n';
	}
	else{
		for(int i = 1; i <= num.size(); ++i){
			ans = ans * 2 % MOD;
		}
		cout << ans << '\n';
	}
	return;
}
int main(){
	ios::sync_with_stdio(false),cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		solve();
	}
} 
posted @ 2026-01-30 14:34  ricky_lin  阅读(6)  评论(0)    收藏  举报