VP Educational Codeforces Round 6
A. Professor GukiZ's Robot
题意:给你两个坐标,可以走八个方向,求从第一个坐标到第二个坐标的最少操作数。
先斜着走,然后到了某个坐标相同的位置就直着走,那么方向就是两个坐标的最远距离。
点击查看代码
void solve() {
int x1, y1, x2, y2;
std::cin >> x1 >> y1 >> x2 >> y2;
int a = std::abs(x1 - x2), b = std::abs(y1 - y2);
std::cout << std::max(a, b) << "\n";
}
B. Grandfather Dovlet’s calculator
题意:1到9的数字有一个值,求一个区间的数字值之和。
点击查看代码
void solve() {
const int N = 1e6 + 5;
std::vector<int> sum(N);
sum[0] = 6; sum[1] = 2; sum[2] = 5; sum[3] = 5; sum[4] = 4; sum[5] = 5; sum[6] = 6;
sum[7] = 3; sum[8] = 7; sum[9] = 6;
for (int i = 10; i <= 1e6; ++ i) {
int tot = 0;
int x = i;
do {
tot += sum[x % 10];
x /= 10;
} while (x);
sum[i] = tot;
}
int a, b;
std::cin >> a >> b;
i64 ans = 0;
for (int i = a; i <= b; ++ i) {
ans += sum[i];
}
std::cout << ans << "\n";
}
C. Pearls in a Row
题意:给你一个数组,你要把它分成最多的块,使得每个块内至少有一个数出现两次以上。
记每个位置上数字出现的下一个位置,然后贪心的取连续一段使得最右边的数字恰好出现两次就行。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::map<int, int> pos;
std::vector<int> next(n, n);
for (int i = n - 1; i >= 0; -- i) {
if (pos.count(a[i])) {
next[i] = pos[a[i]];
}
pos[a[i]] = i;
}
std::vector<std::pair<int, int>> ans;
for (int i = 0; i < n; ++ i) {
int j = i, r = next[i];
while (j < r) {
r = std::min(r, next[j]);
++ j;
}
if (r == n) {
if (ans.empty()) {
std::cout << -1 << "\n";
return;
} else {
ans.back().second = n - 1;
break;
}
}
ans.push_back({i, j});
i = j;
}
std::cout << ans.size() << "\n";
for (auto & [l, r] : ans) {
std::cout << l + 1 << " " << r + 1 << "\n";
}
}
D. Professor GukiZ and Two Arrays
这题调红温了,思路是对的但一直wa。
题意:给你两个数组,你可以交换两个数组的数,不超过两个,使得两个数组和的差的绝对值最小。
交换一对
交换两对
对于第二种情况,把所有
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<i64> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
int m;
std::cin >> m;
std::vector<i64> b(m);
for (int i = 0; i < m; ++ i) {
std::cin >> b[i];
}
i64 suma = std::accumulate(a.begin(), a.end(), 0ll);
i64 sumb = std::accumulate(b.begin(), b.end(), 0ll);
std::vector<std::array<i64, 3>> A, B;
for (int i = 0; i < n; ++ i) {
for (int j = i + 1; j < n; ++ j) {
A.push_back({2 * (a[i] + a[j]), i, j});
}
}
for (int i = 0; i < m; ++ i) {
for (int j = i + 1; j < m; ++ j) {
B.push_back({2 * (b[i] + b[j]), i, j});
}
}
std::sort(A.begin(), A.end());
std::sort(B.begin(), B.end());
i64 ans2 = 1e18;
std::vector<std::pair<int, int>> op2;
for (auto & [x, i, j] : A) {
i64 v = suma - sumb - x;
if (v <= 0) {
int p = std::lower_bound(B.begin(), B.end(), std::array<i64, 3>{std::abs(v), 0, 0}) - B.begin();
if (p != B.size()) {
if (std::abs(suma - sumb - x + B[p][0]) < ans2) {
ans2 = std::abs(suma - sumb - x + B[p][0]);
op2.clear();
op2.push_back({i, B[p][1]});
op2.push_back({j, B[p][2]});
}
}
if (p != 0) {
-- p;
if (std::abs(suma - sumb - x + B[p][0]) < ans2) {
ans2 = std::abs(suma - sumb - x + B[p][0]);
op2.clear();
op2.push_back({i, B[p][1]});
op2.push_back({j, B[p][2]});
}
}
} else {
int l = 0, r = (int)B.size() - 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (-B[mid][0] >= v) {
l = mid;
} else {
r = mid - 1;
}
}
int p = l;
if (p >= 0 && p <= (int)B.size() - 1 && std::abs(suma - sumb - x + B[p][0]) < ans2) {
ans2 = std::abs(suma - sumb - x + B[p][0]);
op2.clear();
op2.push_back({i, B[p][1]});
op2.push_back({j, B[p][2]});
}
if (p < (int)B.size() - 1) {
++ p;
if (p >= 0 && std::abs(suma - sumb - x + B[p][0]) < ans2) {
ans2 = std::abs(suma - sumb - x + B[p][0]);
op2.clear();
op2.push_back({i, B[p][1]});
op2.push_back({j, B[p][2]});
}
}
}
}
i64 ans1 = 1e18;
std::pair<int, int> op1;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
if (std::abs(suma - sumb - 2 * a[i] + 2 * b[j]) < ans1) {
ans1 = std::abs(suma - sumb - 2 * a[i] + 2 * b[j]);
op1 = {i, j};
}
}
}
i64 ans0 = std::abs(suma - sumb);
if (ans0 <= ans1 && ans0 <= ans2) {
std::cout << ans0 << "\n";
std::cout << 0 << "\n";
} else if (ans1 <= ans2 && ans1 <= ans0) {
std::cout << ans1 << "\n";
std::cout << 1 << "\n";
std::cout << op1.first + 1 << " " << op1.second + 1 << "\n";
} else {
std::cout << ans2 << "\n";
std::cout << 2 << "\n";
for (auto & [x, y] : op2) {
std::cout << x + 1 << " " << y + 1 << "\n";
}
}
}
E. New Year Tree
题意:给你一棵树,每个节点有一个颜色,有两种操作,问一棵子树的节点有多少不同的颜色,或者把一棵子树染成同一种颜色。
观察到颜色数很少,可以用线段树维护dfs序,那么一棵子树就是一段区间,颜色可以用一个longlong类型存,或者用bitset。
点击查看代码
#define ls (u << 1)
#define rs (u << 1 | 1)
#define umid (tr[u].l + tr[u].r >> 1)
template <class Info, class Tag>
struct Node {
int l, r;
Info info;
Tag tag;
};
template <class Info, class Tag>
struct SegmentTreeWithLazy {
std::vector<Node<Info, Tag> > tr;
SegmentTreeWithLazy(int _n) {
init(_n);
}
SegmentTreeWithLazy(int _n, std::vector<Info> & a) {
init(_n, a);
}
void init(int _n) {
tr.assign(_n << 2, {});
build(1, _n);
}
void init(int _n, std::vector<Info> & a) {
tr.assign(_n << 2, {});
build(1, _n, a);
}
void pushup(int u) {
tr[u].info = tr[ls].info + tr[rs].info;
}
void pushdown(Node<Info, Tag> & u, Tag tag) {
u.info = u.info + tag;
u.tag = u.tag + tag;
}
void pushdown(int u) {
if (tr[u].tag.exist()) {
pushdown(tr[ls], tr[u].tag);
pushdown(tr[rs], tr[u].tag);
tr[u].tag.clear();
}
}
void build(int l, int r, int u = 1) {
tr[u] = {l, r, {}};
if (l == r) {
return;
}
int mid = l + r >> 1;
build(l, mid, ls); build(mid + 1, r, rs);
}
void build(int l, int r, std::vector<Info> & a, int u = 1) {
tr[u] = {l, r, {}};
if (l == r) {
tr[u].info = a[l];
return;
}
int mid = l + r >> 1;
build(l, mid, a, ls); build(mid + 1, r, a, rs);
pushup(u);
}
void modify(int l, int r, Tag tag, int u = 1) {
if (l <= tr[u].l && tr[u].r <= r) {
pushdown(tr[u], tag);
return;
}
pushdown(u);
int mid = umid;
if (l <= mid) {
modify(l, r, tag, ls);
}
if (r > mid) {
modify(l, r, tag, rs);
}
pushup(u);
}
Info query(int l, int r, int u = 1) {
if (l <= tr[u].l && tr[u].r <= r) {
return tr[u].info;
}
pushdown(u);
int mid = umid;
if (r <= mid) {
return query(l, r, ls);
} else if (l > mid) {
return query(l, r, rs);
}
return query(l, r, ls) + query(l, r, rs);
}
};
const int N = 61;
struct Info {
std::bitset<N> s;
};
struct Tag {
int c;
bool exist() {
return c != 0;
}
void clear() {
c = 0;
}
};
Info operator + (Info a, Info b) {
a.s |= b.s;
return a;
}
Info operator + (Info a, Tag b) {
std::bitset<N> s;
s[b.c] = 1;
return {s};
}
Tag operator + (Tag a, Tag b) {
return b;
}
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n + 1);
for (int i = 1; i <= n; ++ i) {
std::cin >> a[i];
}
std::vector<std::vector<int>> adj(n + 1);
for (int i = 1; i < n; ++ i) {
int u, v;
std::cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
std::vector<int> l(n + 1), r(n + 1);
int dfn = 0;
auto dfs = [&](auto self, int u, int fa) -> void {
l[u] = ++ dfn;
for (auto & v : adj[u]) {
if (v == fa) {
continue;
}
self(self, v, u);
}
r[u] = ++ dfn;
};
dfs(dfs, 1, 0);
SegmentTreeWithLazy<Info, Tag> tr(dfn + 1);
for (int i = 1; i <= n; ++ i) {
tr.modify(l[i], l[i], Tag{a[i]});
tr.modify(r[i], r[i], Tag{a[i]});
}
while (m -- ) {
int op, v, x;
std::cin >> op >> v;
if (op == 1) {
std::cin >> x;
tr.modify(l[v], r[v], Tag{x});
} else {
std::cout << tr.query(l[v], r[v]).s.count() << "\n";
}
}
}
F. Xors on Segments
题意:定义
考虑暴力怎么做,就是每次两次循环枚举
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
const int N = 1e6 + 5;
std::vector<int> sum(N);
for (int i = 1; i < N; ++ i) {
sum[i] = sum[i - 1] ^ i;
}
std::vector<int> a(n + 1);
for (int i = 1; i <= n; ++ i) {
std::cin >> a[i];
}
std::vector<int> l(m), r(m), ans(m);
for (int i = 0; i < m; ++ i) {
std::cin >> l[i] >> r[i];
}
std::vector<int> f(n + 1);
for (int i = 1; i <= n; ++ i) {
f[i] = a[i];
for (int j = i + 1; j <= n; ++ j) {
f[j] = std::max(f[j - 1], sum[std::max(a[i], a[j])] ^ sum[std::min(a[i], a[j]) - 1]);
}
for (int j = 0; j < m; ++ j) {
if (i >= l[j] && i <= r[j]) {
ans[j] = std::max(ans[j], f[r[j]]);
}
}
}
for (int i = 0; i < m; ++ i) {
std::cout << ans[i] << "\n";
}
}
分类:
codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具