Идея: Vladosiya Разработка: Vladosiya
Разбор
Tutorial is loading...
Решение
def solve():
n, m = map(int, input().split())
a = input()
ans = 0
for ch in range(ord('A'), ord('H')):
ans += max(0, m - a.count(chr(ch)))
print(ans)
for _ in range(int(input())):
solve()
Идея: senjougaharin Разработка: senjougaharin
Разбор
Tutorial is loading...
Решение
def solve():
n, f, k = map(int, input().split())
f -= 1
k -= 1
a = list(map(int, input().split()))
x = a[f]
a.sort(reverse=True)
if a[k] > x:
print("NO")
elif a[k] < x:
print("YES")
else:
print("YES" if k == n - 1 or a[k + 1] < x else "MAYBE")
t = int(input())
for _ in range(t):
solve()
1980C - София и утерянные операции
Идея: senjougaharin Разработка: Gornak40
Разбор
Tutorial is loading...
Решение
#include <stdio.h>
#include <stdbool.h>
#define MAXN 200200
#define MAXM 200200
int n, m, k;
int arr[MAXN], brr[MAXN], drr[MAXM], buf[MAXN];
int cmp_i32(const void* pa, const void* pb) {
return *(const int*)pa - *(const int*)pb;
}
void build() {
k = 0;
for (int i = 0; i < n; ++i) {
if (arr[i] != brr[i])
buf[k++] = brr[i];
}
qsort(buf, k, sizeof(*buf), cmp_i32);
}
bool check() {
for (int i = 0; i < n; ++i)
if (brr[i] == drr[m - 1])
return true;
return false;
}
bool solve() {
if (!check()) return false;
qsort(drr, m, sizeof(*drr), cmp_i32);
int ib = 0, id = 0;
while (ib < k && id < m) {
if (buf[ib] == drr[id])
++ib, ++id;
else if (buf[ib] < drr[id])
return false;
else ++id;
}
return ib == k;
}
int main() {
int t; scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d", arr + i);
for (int i = 0; i < n; ++i)
scanf("%d", brr + i);
scanf("%d", &m);
for (int j = 0; j < m; ++j)
scanf("%d", drr + j);
build();
if (solve()) printf("YES\n");
else printf("NO\n");
}
}
1980D - НОД-последовательность
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
bool good(vector<int>&b){
int g = __gcd(b[0], b[1]);
for(int i = 1; i < int(b.size()) - 1; i++){
int cur_gcd = __gcd(b[i], b[i + 1]);
if(g > cur_gcd) return false;
g = cur_gcd;
}
return true;
}
bool solve(){
int n;
cin >> n;
vector<int>a(n);
for(int i = 0; i < n; i++){
cin >> a[i];
}
int g = -1;
int to_del = -1;
for(int i = 0; i < n - 1; i++){
int cur_gcd = __gcd(a[i], a[i + 1]);
if(cur_gcd < g){
to_del = i;
break;
}
g = cur_gcd;
}
if(to_del == -1) return true;
vector<int>b0 = a, b1 = a, b2 = a;
if(to_del > 0) b0.erase(b0.begin() + to_del - 1);
b1.erase(b1.begin() + to_del);
if(to_del < n - 1) b2.erase(b2.begin() + to_del + 1);
return good(b0) || good(b1) || good(b2);
}
int main(){
int t;
cin >> t;
while(t--){
cout << (solve() ? "YES" : "NO") << "\n";
}
}
1980E - Перестановка строк и столбцов
Идея: senjougaharin Разработка: senjougaharin
Разбор
Tutorial is loading...
Решение
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
vi read_ints(int n) {
vi res(n);
for (int i = 0; i < n; ++i) {
cin >> res[i];
}
return res;
}
vvi read_matrix(int n, int m) {
vvi res(n);
for (int i = 0; i < n; ++i) {
res[i] = read_ints(m);
}
return res;
}
void solve() {
int n, m;
cin >> n >> m;
vvi a = read_matrix(n, m), b = read_matrix(n, m);
int nm = n * m;
vi pos1i(nm), pos2i(nm), pos1j(nm), pos2j(nm);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
int x = a[i][j] - 1;
int y = b[i][j] - 1;
pos1i[x] = pos2i[y] = i;
pos1j[x] = pos2j[y] = j;
}
}
vector<set<int>> pi(nm), pj(nm);
for (int x = 0; x < nm; ++x) {
int i1 = pos1i[x], i2 = pos2i[x];
int j1 = pos1j[x], j2 = pos2j[x];
pi[i1].insert(i2);
pj[j1].insert(j2);
}
for (int x = 0; x < nm; ++x) {
if (pi[x].size() > 1 || pj[x].size() > 1) {
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
int main() {
int t;
cin >> t;
for (int _ = 0; _ < t; ++_) {
solve();
}
return 0;
}
1980F1 - Разделение поля (простая версия)
Идея: MikeMirzayanov Разработка: Vladosiya
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
#define int long long
#define pb emplace_back
#define mp make_pair
#define x first
#define y second
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
typedef long double ld;
typedef long long ll;
using namespace std;
mt19937 rnd(time(nullptr));
const ll inf = 1e9 + 1;
const ll M = 998244353;
const ld pi = atan2(0, -1);
const ld eps = 1e-6;
bool cmp(pair<int, int> &a, pair<int, int> &b){
if(a.x != b.x) return a.x > b.x;
return a.y < b.y;
}
void solve(int tc){
int n, m, k;
cin >> n >> m >> k;
vector<pair<int, int>> a(k);
map<pair<int, int>, int> idx;
for(int i = 0; i < k; ++i){
cin >> a[i].x >> a[i].y;
idx[a[i]] = i;
}
sort(all(a), cmp);
vector<int> ans(k);
int total = 0;
int cur = m + 1;
int last = n;
for(auto e: a){
if(cur > e.y) {
ans[idx[e]] = 1;
total += (cur - 1) * (last - e.x);
cur = e.y;
last = e.x;
}
}
total += (cur - 1) * last;
cout << total << "\n";
for(int e: ans) cout << e << " ";
}
bool multi = true;
signed main() {
int t = 1;
if (multi)cin >> t;
for (int i = 1; i <= t; ++i) {
solve(i);
cout << "\n";
}
return 0;
}
1980F2 - Разделение поля (сложная версия)
Идея: MikeMirzayanov Разработка: Vladosiya
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
#define int long long
#define pb emplace_back
#define mp make_pair
#define x first
#define y second
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
typedef long double ld;
typedef long long ll;
using namespace std;
mt19937 rnd(time(nullptr));
const ll inf = 1e9 + 1;
const ll M = 998244353;
const ld pi = atan2(0, -1);
const ld eps = 1e-6;
bool cmp(pair<int, int> &a, pair<int, int> &b){
if(a.x != b.x) return a.x > b.x;
return a.y < b.y;
}
void solve(int tc){
int n, m, k;
cin >> n >> m >> k;
vector<pair<int, int>> a(k);
map<pair<int, int>, int> idx;
for(int i = 0; i < k; ++i){
cin >> a[i].x >> a[i].y;
idx[a[i]] = i;
}
idx[{0, 0}] = k++;
a.emplace_back(0, 0);
sort(all(a), cmp);
vector<int> ans(k);
vector<int> total(k + 1), cur(k + 1, m + 1), last(k + 1, n);
for(int i = 1; i <= k; ++i){
auto e = a[i - 1];
total[i] = total[i - 1];
cur[i] = cur[i - 1];
last[i] = last[i - 1];
if(cur[i] > e.y) {
ans[idx[e]] = 1;
total[i] += (cur[i] - 1) * (last[i] - e.x);
cur[i] = e.y;
last[i] = e.x;
}
}
cout << total[k] << "\n";
for(int i = 1; i <= k; ++i){
auto e = a[i - 1];
if(ans[idx[e]] == 0)continue;
int tot = total[i - 1];
int cr = cur[i - 1];
int lst = last[i - 1];
for(int j = i + 1; j <= k; ++j){
auto ee = a[j - 1];
if(cr > ee.y){
tot += (cr - 1) * (lst - ee.x);
cr = ee.y;
lst = ee.x;
}
if(ans[idx[ee]] == 1){
ans[idx[e]] = tot - total[j];
break;
}
}
}
ans.pop_back();
for(int e: ans) cout << e << " ";
}
bool multi = true;
signed main() {
int t = 1;
if (multi)cin >> t;
for (int i = 1; i <= t; ++i) {
solve(i);
cout << "\n";
}
return 0;
}
1980G - Яся и таинственное дерево
Идея: Gornak40 Разработка: Gornak40
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
struct trie {
int l, c;
vector<array<int, 2>> node;
vector<int> cnt;
trie(int l, int max_members) : l(l), c(0), node((l + 2) * max_members + 3), cnt((l + 2) * max_members + 3) {}
void add(int x) {
int cur = 0;
for (int i = l; i >= 0; --i) {
bool has_bit = (1 << i) & x;
if (!node[cur][has_bit]) {
node[cur][has_bit] = ++c;
}
cur = node[cur][has_bit];
++cnt[cur];
}
}
void remove(int x) {
int cur = 0;
for (int i = l; i >= 0; --i) {
bool has_bit = (1 << i) & x;
if (!node[cur][has_bit]) {
node[cur][has_bit] = ++c;
}
cur = node[cur][has_bit];
--cnt[cur];
}
}
int find_max(int x) {
int cur = 0, ans = 0;
for (int i = l; i >= 0; --i) {
bool has_bit = (1 << i) & x;
if (node[cur][!has_bit] && cnt[node[cur][!has_bit]]) {
ans += 1 << i;
cur = node[cur][!has_bit];
}
else {
cur = node[cur][has_bit];
}
}
return ans;
}
};
const int N = 2e5 + 2;
int x[N];
bitset<N> dp;
vector<array<int, 2>> e[N];
void dfs(int c, int p) {
for (auto [i, w] : e[c]) {
if (i == p) {
continue;
}
dp[i] = !dp[c];
x[i] = x[c] ^ w;
dfs(i, c);
}
}
void solve() {
int n, m, gx = 0;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
e[i].clear();
}
for (int i = 1, u, v, w; i < n; ++i) {
cin >> u >> v >> w;
e[u].push_back({v, w});
e[v].push_back({u, w});
}
dfs(1, 0);
vector<trie> t(2, trie(30, n));
for (int i = 1; i <= n; ++i) {
t[dp[i]].add(x[i]);
}
while (m--) {
char c;
cin >> c;
if (c == '^') {
int y;
cin >> y;
gx ^= y;
}
else {
int a, b;
cin >> a >> b;
t[dp[a]].remove(x[a]);
int same_group = t[dp[a]].find_max(x[a] ^ b);
int diff_group = t[1 - dp[a]].find_max(x[a] ^ b ^ gx);
t[dp[a]].add(x[a]);
cout << max(same_group, diff_group) << "\n";
}
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}