Codeforces Div2 2025.11.28
https://codeforces.com/contest/2170
B. Addition on a Segment
题目大意:
有一个长度为 \(n\) 初始全为 \(0\) 的序列 \(a\),并且给定一个确认的序列 \(b\) (\(0\leq b_i\leq n\)),每次可以选择一个区间 \([\ l,\ r\ ]\) 使得 \(a[l...r]\) 都加 \(1\),并且必须要操作 \(n\) 次使得 \(a\) 变成 \(b\),问 \(n\) 次操作中最大的 \(r-l+1\) 是多少
Solution:
因为必须要操作 \(n\) 次,而我们想要去最大化操作长度,所以让前 \(n-1\) 次操作只让某个数 \(+1\), 然后就可以让第 \(n\) 次操作的长度尽可能长了,并且操作的最大长度是原序列长度减去 \(0\) 的个数,因为显然不能对 \(0\) 进行加的操作,然后取一个 \(min\) 就好
namespace Solution{
int n;
void Main(){
cin >> n;
vector<int> a(n + 1);
int zero = 0;
For (i, 1, n) cin >> a[i];
For (i, 1, n) if (a[i] == 0) zero++;
int sum = 0;
For (i, 1, n) sum += a[i];
cout << min(sum - (n - 1), n - zero) << endl;
}
};
C. Quotient and Remainder
题目大意:
有两个长度为 \(n\) 的数组 \(q\), \(r\), 给定一个 \(k\),选择两个数 \(x,y\) 满足 \(1\leq y\le x\leq k\),其中在 \(q\) 中删除 \(q_i=x/y\),在 \(r\) 中删除 \(r_j=x\%y\),问最多能删除几个数
Solution:
可以得出这个式子 \(q_j*y+r_i=x\),很显然 \(y> r_i\),而我们要让 \(x\) 尽可能的小,就不妨让 \(y=r_i+1\), 此时 \(q=(x-r)/(r+1)\),并且让 \(x\) 取到 \(k\),同时也让 \(q\) 取到能取到的最大。
如果最大的 \(r\) 能匹配到一个 \(q\),那么说明其余的 \(r\) 也可以用这个 \(q\),所以按照 \(r\) 从大到小排序
namespace Solution{
int n, k;
void Main(){
cin >> n >> k;
vector<int> q(n + 1), r(n + 1);
For (i, 1, n) cin >> q[i];
For (i, 1, n) cin >> r[i];
// sort(r.begin() + 1, r.end(), greater<int>());
multiset<int> Q(q.begin() + 1, q.end());
int ans = 0;
For (i, 1, n){
int rr = r[i];
int yy = (k - rr) / (rr + 1);
auto it = Q.upper_bound(yy);
if (it != Q.begin()){
ans++;
Q.erase(prev(it));
}
}
cout << ans << endl;
}
}
E. Binary Strings and Blocks
题目大意:
定义一个块为一个 \(01\) 字符串中连续的一部分, 一个块是美丽的当且仅当移除一个块后块的个数为奇数。
当前有 \(m\) 个约束 \(l_i,\ r_i\) 使得字符串在 \(s[l_i\rightarrow r_i]\) 是美丽的,问满足这些条件的长度为 \(n\) 的字符串的个数是多少
Solution:
首先一个字符串是美丽的只有它多于 \(1\) 个块就行
设 \(dp[\ i\ ]\) 表示长度为 \(i\) 的答案数,其中在第 \(i\) 位改变 \(01\) 也就是与第 \(i-1\) 位不一样。考虑所有的右端点小于 \(i\) 中左端点最大的 \(j\) 是多少。因为比如满足 \((3,7)\) 是美丽的,那么 \((2,8)\) 也一定是美丽的。所以可以从 \(j\) 转移到 \(i\),并且此时情况数要减去 \(j\) 前面的所有情况。如果没有左端点的话,那么就 \(*2\)。
最后答案要 \(*2\) 因为我们目前只考虑了第一位是 \(1\) 的情况,第一位是 \(0\) 的话和是 \(1\) 是一样的。
namespace Solution{
int n, m;
void Main(){
cin >> n >> m;
vector<int> lmax(n + 5);
For (i, 1, m){
int l, r;
cin >> l >> r;
upmax(lmax[r], l);
}
For (i, 1, n){
upmax(lmax[i], lmax[i - 1]);
}
vector<int> dp(n + 5);
vector<int> sum(n + 5);
dp[0] = 1;
sum[0] = 1;
For (i, 1, n){
int tmp = sum[i - 1];
if (lmax[i]){
tmp = (tmp - sum[lmax[i] - 1] + mod) % mod;
}
dp[i] = tmp;
sum[i] = (sum[i - 1] + dp[i]) % mod;
}
cout << dp[n] * 2 % mod << endl;
}
};

浙公网安备 33010602011771号