Educational Codeforces Round 22
Educational Codeforces Round 22
艰难
https://codeforces.com/contest/813
A. The Contest
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1005;
ll n, m, sum, x;
int main () {
cin >> n;
for (int i = 1; i <= n; i++) cin >> x, sum += x;
cin >> m;
for (int i = 1; i <= m; i++) {
ll l, r;
cin >> l >> r;
if (r >= sum) {
cout << max (sum, l);
return 0;
}
}
cout << -1;
}
//贪心
//前缀和+差分
B. The Golden Age
直接枚举,数据非常极端以至于边界判断很严格,稍微多乘一次就会溢出!!!!WA了114514次
#include <bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
signed main () {
ll x, y, l, r;
cin >> x >> y >> l >> r;
set<ll> s;
s.insert (l - 1), s.insert (r + 1);
for (int a = 1; ; a *= x) {
for (int b = 1; ; b *= y) {
ll n = a + b;
if (n >= l && n <= r) s.insert (n);
if (r / b < y) break;
}
if (r / a < x) break;
}
//for (auto i : s) cout << i << ' '; cout << endl;
ll ans = 0;
for (auto it = s.begin (); it != s.end (); it++) {
if (it == s.begin ()) continue;
ans = max (ans, *it - *(prev(it)) - 1);
}
cout << ans << endl;
}
//呜呜只能想到暴力
//优化: 幂指数增长很快, 所以是有限的
C. The Tag Game
B分两种情况:一直往下跳 / 往回走一下再跳到别的地方
故要两个数组:dep记录深度之差(路径长度),down记录当前分支往下的最大深度,从b点开始搜,记录最大值。注意处理跳上来就碰到的情况。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, M = N * 2;
int h[N], ne[M], e[M], idx;
int n, m, dep[N], ans, down[N], p[N];
void add (int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void dfs (int u, int fa) {
dep[u] = dep[fa] + 1;
p[u] = fa; //记录前驱,往前跳
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (j == fa) continue;
ans = max (ans, dep[j]);
dfs (j, u);
down[u] = max(down[u], down[j] + 1); //往下走最远能走去哪
}
}
void dfs2 (int u) {
if (u == -1) return ; //re
if (dep[m] - dep[u] >= dep[u] - dep[1]) return ;//转弯之前遇见
ans = max (ans, 2 * (dep[u] - dep[1] + down[u]));
dfs2 (p[u]);
}
int main () {
memset (h, -1, sizeof h);
cin >> n >> m;
int fm = 1;
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
add (a, b), add (b, a);
}
dfs (1, -1);
ans = dep[m] - dep[1];
dfs2 (m);
//for (int i = 1; i <= n; i++) cout << dep[i] << ' '; cout << endl;
cout << ans;
}
//当前分支往下的最大深度