NOTE比赛链接:牛客周赛 Round 143
A - 小红的区间构造
关键词:签到
Code
// Problem: 小红的区间构造// Contest: NowCoder// URL: https://ac.nowcoder.com/acm/contest/134529/A// Time: 2026-05-10 19:00:07
#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ ll n; cin >> n; cout << 1 << " " << n << endl;}
int main(){ fastio();
int T = 1; // cin >> T;
while (T--) solve();
return 0;}B - 小红的冷门副本
关键词:思维
思路
由于 的范围太大,如果开数组一定会超空间,假如开 map 正着遍历又会超时间。
我们考虑反着做,统计 的所有副本,用总数减掉即可。
Code
// Problem: 小红的冷门副本// Contest: NowCoder// URL: https://ac.nowcoder.com/acm/contest/134529/B// Time: 2026-05-10 19:01:08#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ ll n, m, x; cin >> n >> m >> x;
map<ll, int> mp;
for (int i = 1; i <= n; i++) { int k; cin >> k; mp[k]++; }
ll cnt = 0; for (auto &[k, v]: mp) if (v > x) cnt++;
cout << m - cnt << endl;}
int main(){ fastio();
int T = 1; // cin >> T;
while (T--) solve();
return 0;}C - 小红的因子幂和
关键词:数学
思路
考虑如何获取所有正因子,实际上直接暴力枚举所有因子,并插入 set 里就可以,set 同时自动去重并排序。
后面乘的过程同理,但注意快速幂开始一定要将底数 a 对 mod 取模,否则会溢出。
Code
// Problem: 小红的因子幂和// Contest: NowCoder// URL: https://ac.nowcoder.com/acm/contest/134529/C// Time: 2026-05-10 19:15:54
#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;const ll mod = 1e9 + 7;
map<ll, int> mp;
ll qmi(ll a, ll k){ ll res = 1; a %= mod; while (k) { if (k & 1) res = (res * a) % mod;
a = (a * a) % mod; k >>= 1; } return res % mod;}
void solve(){ ll x, y; cin >> x >> y;
set<ll> s1, s2;
for (ll i = 1; i <= x / i; i++) { if (x % i != 0) continue;
s1.insert(i); s1.insert(x / i); }
// cout << s1.size() << endl;
for (ll i = 1; i <= y / i; i++) { if (y % i != 0) continue;
s2.insert(i); s2.insert(y / i); }
set<ll> f; for (auto t1: s1) for (auto t2: s2) f.insert(t1 * t2);
ll res = 0; for (auto i: f) res = (res + qmi(i, i)) % mod;
cout << res << endl;}
int main(){ fastio();
int T = 1; // cin >> T;
while (T--) solve();
return 0;}D - 小红的最佳区间
关键词:思维,差分
思路
我们需要做一步转化,需要将“给定区间与滑动区间相交”这个条件,转化成计算 L 的合法取值范围。
假设我们选择的区间是 ,给定的第 个区间是 。 两个闭区间相交的充要条件是:它们的最大左端点,必须小于等于最小右端点,即 。
把这个不等式拆开,有 ,。
综上,L满足的范围是 。
现在问题转化为了:已知 个新的区间 ,求坐标轴上的哪一个点(即 的取值)被覆盖的次数最多。
使用 map 对原数组离散化,并作差分即可。
Code
// Problem: 小红的最佳区间// Contest: NowCoder// URL: https://ac.nowcoder.com/acm/contest/134529/D// Time: 2026-05-10 19:59:49#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ int n, k; cin >> n >> k;
map<ll, int> mp;
for (int i = 1; i <= n; i++) { ll l, r; cin >> l >> r;
mp[l - k]++; mp[r + 1]--; }
ll res = -1, tmp = 0;
for (auto &[k, val]: mp) { tmp += val; if (tmp > res) res = tmp; }
cout << res << endl;}
int main(){ fastio();
int T = 1; // cin >> T;
while (T--) solve();
return 0;}E - 小红的好矩阵
关键词:分类讨论,构造
思路
首先考虑不可能修改到合法的情况:当 不能被 整除时,怎样修改都不合法。
要让一个 的 01 矩阵合法(即所有 0 连通块和 1 连通块的大小都恰好为 3),我们可以从图形拼接的角度来推导其所有合法的形态。实际上可以枚举出 种基本的图形块。
L型结构:
- 组(左侧为0,右侧为1):
A1: 第一行001,第二行011B1: 第一行011,第二行001
- 组(左侧为1,右侧为0):
A2: 第一行110,第二行100B2: 第一行100,第二行110
横条结构:
C1: 第一行000,第二行111C2: 第一行111,第二行000

NOTE赛时想到了分类讨论,但没有想到按左右侧分0和1讨论,还是思路不够清晰,实际上正常的讨论方式就是这样。
为了让相邻的 块拼在一起时,边界的连通块不会意外合并导致大小超过 3,只有以下四种相互独立的拼接模式是合法的:
模式 1:任意拼接 A1 和 B1:
由于 A1 和 B1 的左边界都是 0/0,右边界都是 1/1。它们拼接时必定是 1/1 贴着 0/0,0 和 1 不会合并。因此,整个序列的每一个 块都可以自由且独立地在 A1 和 B1 中二选一。
模式 2:任意拼接 A2 和 B2:
同理,左边界 1/1,右边界 0/0,每一个块都能在 A2 和 B2 中二选一。
模式 3:交替拼接 C1, C2, C1, C2...
因为 C1 会在右侧留下 0/1 的缺口,如果紧接 C1,就会导致 0 连通块合并为 6。因此它必须且只能接上 C2(左侧为 1/0)。
模式 4:交替拼接 C2, C1, C2, C1...
将原矩阵按 划分为 个子块。 对于第 个子块,统计它变成 A1, B1, A2, B2, C1, C2 各需要修改多少次字符(即汉明距离)。 然后分别计算将整个矩阵变为以上 4 个模式所需的最小总修改次数,取其中的最小值即为答案。
NOTE关键在于拼接的时候,每个联通块不能互相干扰,否则就不满足题目的限制条件。
这样其实更好做了。
Code
// Problem: 小红的好矩阵// Contest: NowCoder// URL: https://ac.nowcoder.com/acm/contest/134529/E// Time: 2026-05-10 20:04:12#include <bits/stdc++.h>using namespace std;
// clang-format off#define endl '\n'#define all(x) (x).begin(), (x).end()#define fastio() ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);// clang-format on
using ll = long long;using ull = unsigned long long;using pii = pair<int, int>;using pdd = pair<double, double>;using pll = pair<long long, long long>;using i128 = __int128;
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};const int inf = 0x3f3f3f3f;const int N = 0;
void solve(){ int n; cin >> n;
string s[2]; cin >> s[0] >> s[1];
if (n % 3 != 0) { cout << "-1" << endl; return; }
// 定义六种基本构成单位 string A1[2] = {"001", "011"}; string B1[2] = {"011", "001"};
string A2[2] = {"110", "100"}; string B2[2] = {"100", "110"};
string C1[2] = {"000", "111"}; string C2[2] = {"111", "000"};
ll k1 = 0, k2 = 0, k3 = 0, k4 = 0;
for (int i = 0; i < n / 3; i++) { int a1 = 0, b1 = 0, a2 = 0, b2 = 0, c1 = 0, c2 = 0;
// 计算当前 2x3 的块变成 6 种基本块分别需要修改多少字符 for (int r = 0; r < 2; r++) for (int c = 0; c < 3; c++) { char ch = s[r][i * 3 + c]; if (ch != A1[r][c]) a1++; if (ch != B1[r][c]) b1++; if (ch != A2[r][c]) a2++; if (ch != B2[r][c]) b2++; if (ch != C1[r][c]) c1++; if (ch != C2[r][c]) c2++; }
// 模式1和模式2是内部独立的,取最优即可 k1 += min(a1, b1); k2 += min(a2, b2);
// 长条块必须交替拼接 if (i % 2 == 0) k3 += c1, k4 += c2; else k3 += c2, k4 += c1; }
ll res = min({k1, k2, k3, k4}); cout << res << endl;}
int main(){ fastio();
int T = 1; // cin >> T;
while (T--) solve();
return 0;}