比赛链接
A题
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
const int N = 3e5 + 5, M = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n;
string s;
void solve()
{
cin >> n >> s;
string str = "";
for (char c : s)
{
if (c >= 'a' && c <= 'z')
str.push_back(c);
}
for (char c : s)
{
if (c >= '0' && c <= '9')
str.push_back(c);
}
for (char c : s)
{
if (c >= 'A' && c <= 'Z')
str.push_back(c);
}
cout << str << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
// cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}
B题
思路
非常明显的二分,注意此题会爆longlong,所以我这里使用了python。
代码
n = int(input())
for i in range(n):
a,b,c,d = map(int,input().split(' '))
low = 0
high = int(1e18)
while low < high:
mid = (low + high + 1) // 2;
if mid * d < b * c:
low = mid
else:
high = mid - 1
print(a - low,end=' ')
print()
C题
思路
暴力枚举 A A A和 B B B的值即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int N = 3e5 + 5, M = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n, c, num, len;
string s1, s2, str;
string func(int x)
{
if (x == 0) return "0";
str = "";
while (x)
{
char c = (x % 10) + '0';
x /= 10;
str.push_back(c);
}
reverse(str.begin(), str.end());
return str;
}
bool check(int x)
{
int y = c - x;
s1 = func(x), s2 = func(y);
return (int)(s1.size() + s2.size() + len + 2) == n;
}
void solve()
{
cin >> n >> c;
num = c;
while (num)
{
len++;
num /= 10;
}
int ans = 0;
for (int i = 0; i <= c; i++)
{
if (check(i))
{
ans++;
}
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
// cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}
D题
思路
从 0 0 0到 n + 1 − k n+1-k n+1−k不断循环填充即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int N = 3e5 + 5, M = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n, k;
void solve()
{
cin >> n >> k;
if (k > n)
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
int op = n + 1 - k;
for (int i = 1; i <= n; i++)
{
cout << (i % op) << " ";
}
cout << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
// cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}
E题
思路
令 l o w = l 1 + l 2 low = l1+l2 low=l1+l2,令 h i g h = r 1 + r 2 high = r1+r2 high=r1+r2,答案就是 [ l o w , h i g h ] [low,high] [low,high]里数位和的最大值。假设当前 h i g h high high数位上的值 o p 1 op1 op1比 l o w low low上的 o p 2 op2 op2大时,我们可以取 o p 1 − 1 op1-1 op1−1,后面全部取 9 9 9。我们通过不断枚举 h i g h high high的最高几位,不断贪心即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int N = 3e5 + 5, M = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
int l, r, L, R;
void solve()
{
cin >> l >> r >> L >> R;
int low = l + L, high = r + R;
vector<int>a, b;
while (low || high)
{
a.push_back(low % 10);
b.push_back(high % 10);
low /= 10, high /= 10;
}
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
int n = a.size();
bool ok = false;
int ans = 0, res = 0;
for (int i = 0; i < n; i++)
{
if (a[i] < b[i])
{
ans = max({ans, res + b[i] - 1 + (n - i - 1) * 9, res + b[i]});
}
else
{
ans = max(ans, res + b[i]);
}
res += b[i];
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}
F题
思路
我们计算每一个节点 u u u距离根节点的距离 d i s t u dist_{u} distu。
根据每个节点的深度,按dfs序依次存到vector中。
使用线段树维护每一个深度中节点的 d i s t u dist_{u} distu的区间最大值。
最后,根据dfs序,二分查找即可。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
typedef long long i64;
typedef unsigned long long u64;
typedef pair<int, int> pii;
const int N = 1e5 + 5, M = 1e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n, q;
int depth[N], dist[N], L[N], R[N], cnt;
vector<pii>mp[N];
vector<int>dep[N];
struct segmenttree
{
struct node
{
int l, r, maxx, tag;
};
vector<node>tree;
segmenttree(): tree(1) {}
segmenttree(int n): tree(n * 4 + 1) {}
void pushup(int u)
{
auto &root = tree[u], &left = tree[u << 1], &right = tree[u << 1 | 1];
root.maxx = max(left.maxx, right.maxx);
}
void pushdown(int u)
{
auto &root = tree[u], &left = tree[u << 1], &right = tree[u << 1 | 1];
if (root.tag != 0)
{
left.tag += root.tag;
right.tag += root.tag;
left.maxx = left.maxx + root.tag;
right.maxx = right.maxx + root.tag;
root.tag = 0;
}
}
void build(int u, int l, int r)
{
auto &root = tree[u];
root = {l, r};
if (l == r)
{
root.maxx = 0;
}
else
{
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int val)
{
auto &root = tree[u];
if (root.l >= l && root.r <= r)
{
root.maxx += val;
root.tag += val;
return;
}
pushdown(u);
int mid = root.l + root.r >> 1;
if (l <= mid) modify(u << 1, l, r, val);
if (r > mid) modify(u << 1 | 1, l, r, val);
pushup(u);
}
int query(int u, int l, int r)
{
auto &root = tree[u];
if (root.l >= l && root.r <= r)
{
return root.maxx;
}
pushdown(u);
int mid = root.l + root.r >> 1;
int res = 0;
if (l <= mid) res = query(u << 1, l, r);
if (r > mid) res = max(res, query(u << 1 | 1, l, r));
return res;
}
};
vector<segmenttree>tree;
void dfs1(int u, int fu, int deep)
{
L[u] = ++cnt;
depth[u] = deep;
dep[deep].push_back(u);
for (auto[v, w] : mp[u])
{
if (v == fu) continue;
dist[v] = dist[u] + w;
dfs1(v, u, deep + 1);
}
R[u] = cnt;
}
void solve(int test_case)
{
cin >> n;
for (int i = 1; i <= n; i++)
{
dep[i].push_back(0);
}
for (int i = 1, a, b, w; i < n; i++)
{
cin >> a >> b >> w;
mp[a].push_back({b, w});
mp[b].push_back({a, w});
}
dfs1(1, -1, 1);
for (int i = 1; i <= n; i++)
{
if (dep[i].size() > 1)
{
int len = dep[i].size();
len--;
segmenttree smt(len);
smt.build(1, 1, len);
for (int j = 1; j < dep[i].size(); j++)
{
smt.modify(1, j, j, dist[dep[i][j]]);
}
tree.push_back(smt);
}
}
cin >> q;
for (int i = 1, u, d; i <= q; i++)
{
cin >> u >> d;
int deep = depth[u] + d;
if (deep > n)
{
cout << -1 << endl;
continue;
}
if (dep[deep].size() < 2)
{
cout << -1 << endl;
continue;
}
int idx = deep - 1;
int l = 1, r = dep[deep].size() - 1;
int ansl = -1, ansr = -1;
while (l < r)
{
int mid = l + r >> 1;
if (L[dep[deep][mid]] >= L[u])
{
r = mid;
ansl = mid;
}
else l = mid + 1;
}
if (L[dep[deep][l]] >= L[u])
{
ansl = l;
}
if (ansl == -1)
{
cout << -1 << endl;
continue;
}
int low = 1, high = dep[deep].size() - 1;
while (low < high)
{
int mid = low + high + 1 >> 1;
if (L[dep[deep][mid]] <= R[u])
{
ansr = mid;
low = mid;
}
else high = mid - 1;
}
if (L[dep[deep][low]] <= R[u])
{
ansr = low;
}
if (ansr == -1)
{
cout << -1 << endl;
continue;
}
if (ansl > ansr)
{
cout << -1 << endl;
}
else
{
cout << tree[idx].query(1, ansl, ansr) - dist[u] << endl;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
// cin >> test;
for (int i = 1; i <= test; i++)
{
solve(i);
}
return 0;
}