Skip to content

Commit 4afaf63

Browse files
committed
Dodano rozwiązanie zadania 'Czekolada' z X OI
1 parent a574b2c commit 4afaf63

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

rozwiazania/x/etap1/cze/cze.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Rozwiązanie zadania 'Czekolada' z I Etapu X OI.
2+
// Autor: Paweł Putra
3+
// Złożoność czasowa: O((n + m) * log(n + m))
4+
// Złożoność pamięciowa: O(n + m)
5+
// Punkty: 100 (upsolve)
6+
7+
#include <bits/stdc++.h>
8+
#define dbg(x) #x << " = " << x << " "
9+
using namespace std;
10+
constexpr int MAXN = 1005, INF = 1'000'000'000;
11+
int x[MAXN], y[MAXN];
12+
13+
int32_t main() {
14+
ios_base::sync_with_stdio(0);
15+
16+
int m, n;
17+
18+
cin >> m >> n;
19+
20+
for (int i = 1; i <= m-1; i++) cin >> x[i];
21+
for (int i = 1; i <= n-1; i++) cin >> y[i];
22+
23+
sort(x + 1, x + m, [](int a, int b) {return a > b;});
24+
sort(y + 1, y + n, [](int a, int b) {return a > b;});
25+
26+
int i = 1, j = 1;
27+
int wynik = 0;
28+
while (i < m && j < n) {
29+
if (x[i] >= y[j]) {
30+
wynik += j * x[i];
31+
i++;
32+
} else {
33+
wynik += i * y[j];
34+
j++;
35+
}
36+
}
37+
38+
while (i < m) wynik += j * x[i], i++;
39+
while (j < n) wynik += i * y[j], j++;
40+
41+
cout << wynik << "\n";
42+
}

rozwiazania/x/etap1/cze/cze88.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Rozwiązanie powolne zadania 'Czekolada' z I Etapu X OI.
2+
// Autor: Paweł Putra
3+
// Złożoność czasowa: O((n + m) * log(n + m))
4+
// Złożoność pamięciowa: O(n + m)
5+
// Punkty: 88 (upsolve)
6+
// Rozwiązanie bez obserwacji, że można zawsze łamać przez całość czekolady bez zmiany wyniku.
7+
8+
#include <bits/stdc++.h>
9+
#define dbg(x) #x << " = " << x << " "
10+
using namespace std;
11+
constexpr int MAXN = 1005, INF = 1'000'000'000;
12+
int x[MAXN], y[MAXN];
13+
14+
struct MinTree {
15+
int t[4 * MAXN], n, *tab;
16+
17+
int ql, qr;
18+
19+
int idx_of_max(int l, int r) {
20+
ql = l, qr = r;
21+
return query(1, 1, n);
22+
}
23+
24+
int query(int pos, int l, int r) {
25+
if (l > qr || r < ql) return 0;
26+
if (l >= ql && r <= qr) return t[pos];
27+
int m = (l + r) / 2;
28+
int idx_l = query(pos * 2, l, m);
29+
int idx_r = query(pos * 2 + 1, m+1, r);
30+
if (tab[idx_l] > tab[idx_r]) return idx_l;
31+
return idx_r;
32+
}
33+
34+
void build(int size, int* tab_ptr) {
35+
n = size;
36+
tab = tab_ptr;
37+
_build(1, 1, n);
38+
}
39+
40+
void _build(int pos, int l, int r) {
41+
if (l == r) {
42+
t[pos] = l;
43+
return;
44+
}
45+
46+
int m = (l + r) / 2;
47+
_build(pos * 2, l, m);
48+
_build(pos * 2 + 1, m + 1, r);
49+
if (tab[t[pos*2]] > tab[t[pos*2+1]]) t[pos] = t[pos*2];
50+
else t[pos] = t[pos*2+1];
51+
}
52+
} best_x, best_y;
53+
54+
// Koszt podzielenia podprostokąta czekolady o współrzędnych łamań [l, r] x [d, u].
55+
// Krawędzi jest (n-1)*m + m * (n-1) <= 2 * n*m <= 2 * 10^6.
56+
// Czyli max wynik <= 2 * 10^9.
57+
int solve(int l, int r, int d, int u) {
58+
int bx = best_x.idx_of_max(l, r);
59+
int by = best_y.idx_of_max(d, u);
60+
if (bx == 0 && by == 0) return 0;
61+
// cerr << dbg(l) << dbg(r) << dbg(d) << dbg(u) << dbg(bx) << dbg(x[bx]) << dbg(by) << dbg(y[by]) << endl;
62+
if (x[bx] > y[by]) {
63+
// cerr << "PO X" << endl;
64+
return x[bx] + solve(l, bx - 1, d, u) + solve(bx + 1, r, d, u);
65+
} else {
66+
// cerr << "PO Y" << endl;
67+
return y[by] + solve(l, r, d, by-1) + solve(l, r, by+1, u);
68+
}
69+
}
70+
71+
72+
int32_t main() {
73+
ios_base::sync_with_stdio(0);
74+
75+
int m, n;
76+
77+
cin >> m >> n;
78+
79+
for (int i = 1; i <= m-1; i++) cin >> x[i];
80+
for (int i = 1; i <= n-1; i++) cin >> y[i];
81+
82+
83+
best_x.build(m, x);
84+
best_y.build(n, y);
85+
cout << solve(1, m-1, 1, n-1) << "\n";
86+
}

0 commit comments

Comments
 (0)