Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int q;
cin >> q;
for (int i = 0; i < q; ++i) {
long long n;
int a, b;
cin >> n >> a >> b;
cout << (n / 2) * min(2 * a, b) + (n % 2) * a << endl;
}
return 0;
}
Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n;
cin >> n;
vector<int> a(n);
int ePref = 0, oPref = 0, eSuf = 0, oSuf = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
if (i & 1) eSuf += a[i];
else oSuf += a[i];
}
int ans = 0;
for (int i = 0; i < n; ++i) {
if (i & 1) eSuf -= a[i];
else oSuf -= a[i];
if (ePref + oSuf == oPref + eSuf) {
++ans;
}
if (i & 1) ePref += a[i];
else oPref += a[i];
}
cout << ans << endl;
return 0;
}
Идея: MikeMirzayanov
Я должен упомянуть этот блог, потому что он потрясающий! Это разбор этой задачи от MikeMirzayanov.
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
typedef pair<int, int> pt;
const int N = 1000 + 7;
int cnt[N];
int a[20][20];
int main() {
int n;
scanf("%d", &n);
forn(i, n * n){
int x;
scanf("%d", &x);
++cnt[x];
}
vector<pair<int, pt>> cells;
forn(i, (n + 1) / 2) forn(j, (n + 1) / 2){
if (i != n - i - 1 && j != n - j - 1)
cells.push_back({4, {i, j}});
else if ((i != n - i - 1) ^ (j != n - j - 1))
cells.push_back({2, {i, j}});
else
cells.push_back({1, {i, j}});
}
for (auto cur : {4, 2, 1}){
int lst = 1;
for (auto it : cells){
if (it.first != cur) continue;
int i = it.second.first;
int j = it.second.second;
while (lst < N && cnt[lst] < cur)
++lst;
if (lst == N){
puts("NO");
return 0;
}
a[i][j] = a[n - i - 1][j] = a[i][n - j - 1] = a[n - i - 1][n - j - 1] = lst;
cnt[lst] -= cur;
}
}
puts("YES");
forn(i, n){
forn(j, n)
printf("%d ", a[i][j]);
puts("");
}
return 0;
}
1118D1 - Кофе и курсовая работа (легкая версия)
Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a.rbegin(), a.rend());
for (int i = 1; i <= n; ++i) {
int sum = 0;
for (int j = 0; j < n; ++j) {
sum += max(a[j] - j / i, 0);
}
if (sum >= m) {
cout << i << endl;
return 0;
}
}
cout << -1 << endl;
return 0;
}
1118D2 - Кофе и курсовая работа (сложная версия)
Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> a;
bool can(int i) {
long long sum = 0; // there can be a bug
for (int j = 0; j < n; ++j) {
sum += max(a[j] - j / i, 0);
}
return sum >= m;
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> n >> m;
a = vector<int>(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a.rbegin(), a.rend());
int l = 1, r = n;
while (r - l > 1) {
int mid = (l + r) >> 1;
if (can(mid)) r = mid;
else l = mid;
}
if (can(l)) cout << l << endl;
else if (can(r)) cout << r << endl;
else cout << -1 << endl;
return 0;
}
1118E - Очередная задача про бал
Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n, k;
cin >> n >> k;
if (n > k * 1ll * (k - 1)) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
int cur = 0;
for (int i = 0; i < n; ++i) {
cur += (i % k == 0);
cout << i % k + 1 << " " << (cur + i % k) % k + 1 << endl;
}
}
return 0;
}
1118F1 - Разрезание дерева (легкая версия)
Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int N = 300 * 1000 + 13;
int n;
int a[N];
vector<int> g[N];
int red, blue;
int ans;
pair<int, int> dfs(int v, int p = -1){
int r = (a[v] == 1), b = (a[v] == 2);
for (auto u : g[v]) if (u != p){
auto tmp = dfs(u, v);
ans += (tmp.first == red && tmp.second == 0);
ans += (tmp.first == 0 && tmp.second == blue);
r += tmp.first;
b += tmp.second;
}
return make_pair(r, b);
}
int main() {
int n;
scanf("%d", &n);
forn(i, n){
scanf("%d", &a[i]);
red += (a[i] == 1);
blue += (a[i] == 2);
}
forn(i, n - 1){
int v, u;
scanf("%d%d", &v, &u);
--v, --u;
g[v].push_back(u);
g[u].push_back(v);
}
ans = 0;
dfs(0);
printf("%d\n", ans);
return 0;
}
1118F2 - Разрезание дерева (сложная версия)
Идея: MikeMirzayanov
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int N = 300 * 1000 + 13;
const int LOGN = 19;
const int MOD = 998244353;
int add(int a, int b){
a += b;
if (a >= MOD)
a -= MOD;
if (a < 0)
a += MOD;
return a;
}
int mul(int a, int b){
return a * 1ll * b % MOD;
}
int a[N];
vector<int> g[N];
int up[N][LOGN];
int d[N];
void init(int v, int p = -1){
for (auto u : g[v]) if (u != p){
up[u][0] = v;
for (int i = 1; i < LOGN; ++i)
up[u][i] = up[up[u][i - 1]][i - 1];
d[u] = d[v] + 1;
init(u, v);
}
}
int lca(int v, int u){
if (d[v] < d[u]) swap(v, u);
for (int i = LOGN - 1; i >= 0; --i)
if (d[up[v][i]] >= d[u])
v = up[v][i];
if (v == u) return v;
for (int i = LOGN - 1; i >= 0; --i)
if (up[v][i] != up[u][i]){
v = up[v][i];
u = up[u][i];
}
return up[v][0];
}
int l[N];
int dp[N][2];
int dfs(int v, int p = -1){
vector<pair<int, int>> cur;
for (auto u : g[v]) if (u != p){
int c = dfs(u, v);
if (c != 0)
cur.push_back(make_pair(c, u));
}
vector<int> vals;
forn(i, cur.size()) if (cur[i].first > 0)
vals.push_back(cur[i].first);
sort(vals.begin(), vals.end());
vals.resize(unique(vals.begin(), vals.end()) - vals.begin());
if (int(vals.size()) > 1){
puts("0");
exit(0);
}
if (a[v] != 0 && !vals.empty() && vals[0] != a[v]){
puts("0");
exit(0);
}
if (a[v] == 0 && cur.empty())
return 0;
if (a[v] == 0 && vals.empty()){
vector<int> pr(1, 1), su(1, 1);
forn(i, cur.size())
pr.push_back(mul(pr.back(), add(dp[cur[i].second][0], dp[cur[i].second][1])));
for (int i = int(cur.size()) - 1; i >= 0; --i)
su.push_back(mul(su.back(), add(dp[cur[i].second][0], dp[cur[i].second][1])));
reverse(su.begin(), su.end());
dp[v][1] = 0;
forn(i, cur.size())
dp[v][1] = add(dp[v][1], mul(mul(pr[i], su[i + 1]), dp[cur[i].second][1]));
dp[v][0] = add(dp[v][0], pr[cur.size()]);
return -1;
}
dp[v][1] = 1;
for (auto it : cur){
if (it.first == -1)
dp[v][1] = mul(dp[v][1], add(dp[it.second][0], dp[it.second][1]));
else
dp[v][1] = mul(dp[v][1], dp[it.second][1]);
}
if (a[v] == 0)
return vals[0];
return (l[a[v]] == v ? -1 : a[v]);
}
int main() {
int n, k;
scanf("%d%d", &n, &k);
forn(i, n)
scanf("%d", &a[i]);
forn(i, n - 1){
int v, u;
scanf("%d%d", &v, &u);
--v, --u;
g[v].push_back(u);
g[u].push_back(v);
}
init(0);
memset(l, -1, sizeof(l));
forn(i, n) if (a[i] != 0)
l[a[i]] = (l[a[i]] == -1 ? i : lca(l[a[i]], i));
for (int i = 1; i <= k; ++i){
if (a[l[i]] != 0 && a[l[i]] != i){
puts("0");
exit(0);
}
a[l[i]] = i;
}
dfs(0);
printf("%d\n", dp[0][1]);
return 0;
}