Разбор
Tutorial is loading...
Решение
#include <set>
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
using namespace std;
const int N = 100 + 13;
int n, m;
int a[N];
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int ans2 = *max_element(a, a + n) + m;
for (int it = 0; it < m; it++) {
int pos = -1;
for (int i = 0; i < n; i++) {
if (pos == -1 || a[i] < a[pos]) {
pos = i;
}
}
assert(pos != -1);
a[pos]++;
}
int ans1 = *max_element(a, a + n);
cout << ans1 << ' ' << ans2 << endl;
}
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
int n;
map<string, int> was;
inline void read() {
cin >> n;
for (int i = 0; i < n; i++) {
int c;
string s;
cin >> c >> s;
sort(s.begin(), s.end());
if (was.count(s) == 0) {
was[s] = c;
} else {
was[s] = min(was[s], c);
}
}
}
inline int getC(string a, string b) {
if (!was.count(a) || !was.count(b)) {
return INF;
}
return was[a] + was[b];
}
inline void solve() {
int ans = INF;
if (was.count("A") && was.count("B") && was.count("C")) {
ans = was["A"] + was["B"] + was["C"];
}
if (was.count("ABC")) {
ans = min(ans, was["ABC"]);
}
ans = min(ans, getC("AB", "C"));
ans = min(ans, getC("A", "BC"));
ans = min(ans, getC("AC", "B"));
ans = min(ans, getC("AB", "BC"));
ans = min(ans, getC("AC", "BC"));
ans = min(ans, getC("AC", "AB"));
if (ans == INF) {
ans = -1;
}
cout << ans << endl;
}
int main () {
read();
solve();
}
Разбор
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;
scanf("%d", &n);
vector<int> a(n);
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
int cntneg = 0;
int cntzero = 0;
vector<int> used(n);
int pos = -1;
for (int i = 0; i < n; ++i) {
if (a[i] == 0) {
used[i] = 1;
++cntzero;
}
if (a[i] < 0) {
++cntneg;
if (pos == -1 || abs(a[pos]) > abs(a[i]))
pos = i;
}
}
if (cntneg & 1)
used[pos] = 1;
if (cntzero == n || (cntzero == n - 1 && cntneg == 1)) {
for (int i = 0; i < n - 1; ++i)
printf("1 %d %d\n", i + 1, i + 2);
return 0;
}
int lst = -1;
for (int i = 0; i < n; ++i) {
if (used[i]) {
if (lst != -1) printf("1 %d %d\n", lst + 1, i + 1);
lst = i;
}
}
if (lst != -1) printf("2 %d\n", lst + 1);
lst = -1;
for (int i = 0; i < n; ++i) {
if (!used[i]) {
if (lst != -1) printf("1 %d %d\n", lst + 1, i + 1);
lst = i;
}
}
return 0;
}
Разбор
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 = 200 * 1000 + 13;
int n;
long long T;
int a[N];
int f[N];
void upd(int x){
for (int i = x; i < N; i |= i + 1)
++f[i];
}
int get(int x){
int res = 0;
for (int i = x; i >= 0; i = (i & (i + 1)) - 1)
res += f[i];
return res;
}
int main() {
scanf("%d%lld", &n, &T);
forn(i, n)
scanf("%d", &a[i]);
vector<long long> sums(1, 0ll);
long long pr = 0;
forn(i, n){
pr += a[i];
sums.push_back(pr);
}
sort(sums.begin(), sums.end());
sums.resize(unique(sums.begin(), sums.end()) - sums.begin());
long long ans = 0;
pr = 0;
upd(lower_bound(sums.begin(), sums.end(), 0ll) - sums.begin());
forn(i, n){
pr += a[i];
int npos = upper_bound(sums.begin(), sums.end(), pr - T) - sums.begin();
ans += (i + 1 - get(npos - 1));
int k = lower_bound(sums.begin(), sums.end(), pr) - sums.begin();
upd(k);
}
printf("%lld\n", ans);
return 0;
}
1042E - Vasya and Magic Matrix
Разбор
Tutorial is loading...
Решение
#include<bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
const int N = 1009;
int mul(int a, int b){
return int(a * 1LL * b % MOD);
}
void upd(int &a, int b){
a += b;
while(a >= MOD) a -= MOD;
while(a < 0) a += MOD;
}
int bp(int a, int n){
int res = 1;
for(; n > 0; n >>= 1){
if(n & 1) res = mul(res, a);
a = mul(a, a);
}
return res;
}
int inv(int a){
int ia = bp(a, MOD - 2);
assert(mul(a, ia) == 1);
return ia;
}
int n, m;
int a[N][N];
int dp[N][N];
int si, sj;
int main() {
//freopen("input.txt", "r", stdin);
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
scanf("%d", &a[i][j]);
scanf("%d %d", &si, &sj);
--si, --sj;
vector <pair<int, pair<int, int> > > v;
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
v.push_back(make_pair(a[i][j], make_pair(i, j)));
sort(v.begin(), v.end());
int l = 0;
int sumDP = 0, sumX = 0, sumY = 0, sumX2 = 0, sumY2 = 0;
while(l < int(v.size())){
int r = l;
while(r < int(v.size()) && v[r].first == v[l].first) ++r;
int il = -1;
if(l != 0) il = inv(l);
for(int i = l; i < r; ++i){
int x = v[i].second.first, y = v[i].second.second;
if(il == -1){
dp[x][y] = 0;
continue;
}
upd(dp[x][y], mul(sumDP, il));
upd(dp[x][y], mul(x, x));
upd(dp[x][y], mul(y, y));
upd(dp[x][y], mul(sumX2, il));
upd(dp[x][y], mul(sumY2, il));
upd(dp[x][y], mul(mul(-x - x, sumX), il));
upd(dp[x][y], mul(mul(-y - y, sumY), il));
}
for(int i = l; i < r; ++i){
int x = v[i].second.first, y = v[i].second.second;
upd(sumDP, dp[x][y]);
upd(sumX2, mul(x, x));
upd(sumY2, mul(y, y));
upd(sumX, x);
upd(sumY, y);
}
l = r;
}
printf("%d\n", dp[si][sj]);
return 0;
}
Разбор
Tutorial is loading...
Решение (O(n log n))
#include <bits/stdc++.h>
using namespace std;
#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define sz(a) int((a).size())
const int N = 1000 * 1000 + 13;
int n, k;
vector<int> g[N];
int ans;
int dfs(int v, int p = -1){
if (g[v].size() == 1)
return 0;
vector<int> cur;
for (auto u : g[v]){
if (u == p) continue;
cur.push_back(dfs(u, v) + 1);
}
sort(cur.begin(), cur.end());
while (sz(cur) >= 2){
if (cur.back() + cur[sz(cur) - 2] <= k)
break;
++ans;
cur.pop_back();
}
return cur.back();
}
int main(){
scanf("%d%d", &n, &k);
forn(i, n - 1){
int v, u;
scanf("%d%d", &v, &u);
--v, --u;
g[v].push_back(u);
g[u].push_back(v);
}
forn(i, n){
if (sz(g[i]) > 1){
dfs(i);
break;
}
}
printf("%d\n", ans + 1);
return 0;
}
Решение (Small to Large, O(n log^2 n))
#include <bits/stdc++.h>
using namespace std;
#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define sz(a) int((a).size())
const int N = 1000 * 1000 + 13;
int n, k;
vector<int> g[N];
multiset<int> val[N];
int ans;
void dfs(int v, int d, int p){
if (g[v].size() == 1){
val[v].insert(d);
return;
}
int bst = -1;
for (auto u : g[v]){
if (u == p) continue;
dfs(u, d + 1, v);
if (bst == -1 || sz(val[u]) > sz(val[bst]))
bst = u;
}
swap(val[bst], val[v]);
for (auto u : g[v]){
if (u == p || u == bst) continue;
for (auto it : val[u]){
int dd = k + 2 * d - it;
auto jt = val[v].upper_bound(dd);
if (jt == val[v].begin()){
val[v].insert(it);
}
else{
--jt;
int t = *jt;
val[v].erase(jt);
val[v].insert(max(it, t));
}
}
}
}
int main(){
scanf("%d%d", &n, &k);
forn(i, n - 1){
int v, u;
scanf("%d%d", &v, &u);
--v, --u;
g[v].push_back(u);
g[u].push_back(v);
}
forn(i, n){
if (sz(g[i]) > 1){
dfs(i, 0, -1);
printf("%d\n", sz(val[i]));
break;
}
}
return 0;
}
Решение (O(n))
#include <bits/stdc++.h>
using namespace std;
#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define sz(a) int((a).size())
const int N = 1000 * 1000 + 13;
int n, k;
vector<int> g[N];
int ans;
int dfs(int v, int p = -1){
if (g[v].size() == 1)
return 0;
vector<int> cur;
for (auto u : g[v]){
if (u == p) continue;
cur.push_back(dfs(u, v) + 1);
}
int pos = -1;
forn(i, sz(cur)) {
if (cur[i] * 2 <= k && (pos == -1 || cur[pos] < cur[i]))
pos = i;
}
if (pos == -1) {
ans += sz(cur) - 1;
return *min_element(cur.begin(), cur.end());
}
int res = -1;
forn(i, sz(cur)) {
if (cur[pos] >= cur[i]) continue;
if (cur[i] + cur[pos] <= k && (res == -1 || cur[i] < cur[res]))
res = i;
}
forn(i, sz(cur))
ans += (cur[i] > cur[pos]);
if (res != -1)
--ans;
return (res == -1 ? cur[pos] : cur[res]);
}
int main(){
scanf("%d%d", &n, &k);
forn(i, n - 1) {
int v, u;
scanf("%d%d", &v, &u);
--v, --u;
g[v].push_back(u);
g[u].push_back(v);
}
forn(i, n) {
if (sz(g[i]) > 1) {
dfs(i);
break;
}
}
printf("%d\n", ans + 1);
return 0;
}