Codeforces Round 1062 (Div. 4)
A. Square?
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int a, b, c, d;
std::cin >> a >> b >> c >> d;
if (a == b && b == c && c == d) {
std::cout << "Yes\n";
} else {
std::cout << "NO\n";
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
B. Your Name
题意:判断两个字符串是不是组成的字符一样。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::string s, t;
std::cin >> s >> t;
int cnt[26]{};
for (auto & c : s) {
++ cnt[c - 'a'];
}
for (auto & c : t) {
if ( -- cnt[c - 'a'] < 0) {
std::cout << "NO\n";
return;
}
}
std::cout << "YES\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
C. Isamatdin and His Magic Wand!
题意:一个数组,你可以交换两个奇偶性不同的数,求交换任意次数组的最小字典序。
如果只有偶数或者奇数无法操作,否则一定可以达到升序。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
bool f[2]{};
for (auto & x : a) {
f[x & 1] = 1;
}
if (f[0] && f[1]) {
std::ranges::sort(a);
}
for (int i = 0; i < n; ++ i) {
std::cout << a[i] << " \n"[i == n - 1];
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
D. Yet Another Array Problem
题意:找一个最小的大于\(1\)的数,使得数组里有一个数和它互质。
这个数一定是一个质数,如果不是质数,则可以用它的最小质因子替换它,这样依然和另一个数互质。
那么枚举质数即可,因为\(a_i \leq 10^{18}\),其包含的不同质因子不超过\(20\)个,那么很快就能找到答案。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
std::vector<int> minp, primes;
void sieve(int n) {
minp.assign(n + 1, 0);
primes.clear();
for (int i = 2; i <= n; ++ i) {
if (minp[i] == 0) {
minp[i] = i;
primes.push_back(i);
}
for (auto p : primes) {
if (i * p > n) {
break;
}
minp[i * p] = p;
if (p == minp[i]) {
break;
}
}
}
}
void solve() {
int n;
std::cin >> n;
std::vector<i64> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
for (auto & p : primes) {
for (int i = 0; i < n; ++ i) {
if (std::gcd(a[i], p) == 1) {
std::cout << p << "\n";
return;
}
}
}
std::cout << -1 << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
sieve(1000);
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
E. khba Loves to Sleep!
题意:\([0, x]\)上有\(n\)个点,你需要选\(k\)个不同的位置,使得这\(n\)个点到其中一个位置的最小距离最大。
考虑二分。
先把数组排序,如果二分距离为\(d\),对于两个点\(a_i, a_{i+1}\)之间,可以选的位置为\([a_i + d, a_{i+1} - d]\)。判断这些位置够不够\(k\)个并且记录一下方案就行。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, k, x;
std::cin >> n >> k >> x;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::ranges::sort(a);
if (a.back() != x) {
a.push_back(2 * x);
}
auto check = [&](int d, bool flag) -> std::pair<bool, std::vector<int>> {
std::vector<int> res;
if (d == 0) {
if (flag) {
for (int i = 0; i < k; ++ i) {
res.push_back(i);
}
}
return {true, res};
}
int last = -2 * x;
int cnt = 0;
for (int i = 0; i < a.size(); ++ i) {
int l = std::max(0, last + d), r = std::min(x, a[i] - d);
if (l <= r) {
cnt += r - l + 1;
if (flag) {
while (l <= r && res.size() < k) {
res.push_back(l);
++ l;
}
}
}
last = a[i];
}
return {cnt >= k, res};
};
int lo = 0, hi = x;
while (lo < hi) {
int mid = lo + hi + 1 >> 1;
if (check(mid, false).first) {
lo = mid;
} else {
hi = mid - 1;
}
}
auto ans = check(lo, true).second;
for (int i = 0; i < k; ++ i) {
std::cout << ans[i] << " \n"[i == k - 1];
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
F. Tree, TREE!!!
题意:对于一棵树,求对于每个点为根的情况下,选任意\(k\)个点能凑出多少不同的\(lca\)。求每个点的答案的和。
考虑对于\(u\),有多少点为根选\(k\)个点可以凑出\(lca = u\)。
那么可以先任意选一个点为根,比如\(1\)。然后\(dfs\)一下记录子树节点个数。那么对于\(u\)子树外的点,不管是谁为根\(u\)的子树依然是这个样子,那么如果\(size_u \geq k\),其它\(n - size_u\)个都可以作为答案。对于\(u\)的一个儿子\(v\),它的子树的任意一个点为根,\(u\)的子树就是\(n - size_v\)个点。那么如果\(n - size_v \geq k\),有\(size_v\)个答案。最后以\(u\)为根显然也是可以的。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, k;
std::cin >> n >> k;
std::vector<std::vector<int>> adj(n);
for (int i = 1; i < n; ++ i) {
int u, v;
std::cin >> u >> v;
-- u, -- v;
adj[u].push_back(v);
adj[v].push_back(u);
}
i64 ans = 0;
std::vector<int> size(n);
auto dfs = [&](auto && self, int u, int fa) -> void {
size[u] = 1;
for (auto & v : adj[u]) {
if (v == fa) {
continue;
}
self(self, v, u);
if (n - size[v] >= k) {
ans += size[v];
}
size[u] += size[v];
}
if (size[u] >= k) {
ans += n - size[u];
}
ans += 1;
};
dfs(dfs, 0, -1);
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
G. Mukhammadali and the Smooth Array
题意:一个数组\(a\),你可以花费\(c_i\)把\(a_i\)改成任何数。求让数组不递减的最小花费。
可以看作选一部分不操作,其它的操作的最小花费。
那么选出不操作的这一部分必须是不递减的。那么我们要让这一部分的\(c_i\)的和最大,这样另一部分的花费才会更小。
那么就是一个\(dp\),\(f_i = c_i + f_j(j <i, a_j \leq a_i)\)。
这是典题,可以用树状数组优化为\(nlogn\)。维护一下前缀最大值就可以。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
template <class T>
struct Fenwick {
int n;
std::vector<T> tr;
Fenwick(int _n) {
init(_n);
}
void init(int _n) {
n = _n;
tr.assign(_n + 1, T{});
}
void add(int x, const T &v) {
for (int i = x; i <= n; i += i & -i) {
tr[i] = tr[i] + v;
}
}
T query(int x) {
T res{};
for (int i = x; i; i -= i & -i) {
res = res + tr[i];
}
return res;
}
T sum(int l, int r) {
return query(r) - query(l - 1);
}
};
struct Info {
i64 max = 0;
};
Info operator + (const Info & a, const Info & b) {
return {std::max(a.max, b.max)};
}
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<int> c(n);
for (int i = 0; i < n; ++ i) {
std::cin >> c[i];
}
auto b = a;
std::ranges::sort(b);
b.erase(std::unique(b.begin(), b.end()), b.end());
for (auto & x : a) {
x = std::ranges::lower_bound(b, x) - b.begin() + 1;
}
int m = b.size();
Fenwick<Info> tr(m + 1);
for (int i = 0; i < n; ++ i) {
tr.add(a[i], Info{tr.query(a[i]).max + c[i]});
}
std::cout << std::accumulate(c.begin(), c.end(), 0ll) - tr.query(m).max << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}

浙公网安备 33010602011771号