我解决的:A、I、B。
没看的:无。
旁观的:C、E、M、K、J、L、H。
看了但没做出来的:D、F、G。
A Accurate Movement
简单题,略。
M Managing Difficulties
简单题,略。
K King’s Children
一个不是很困难的构造,略。
E Equidistant
题意;给定一个树,有 m m m 个关键点,问树上有无某个点使得这个点到每一个关键点的距离相同。
把所有关键点放进队列里 BFS,对每个点统计离其最近的关键点个数即可。
#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> G[200005];
queue<int> q;
int cnt[200005] = {
0}, dis[200005];
int main(){
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i < n; ++i){
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(dis, 0x3f, sizeof(dis));
for (int i = 1, t; i <= m; ++i){
scanf("%d", &t);
q.push(t), cnt[t] = 1, dis[t] = 0;
}
while (!q.empty()){
int h = q.front();
q.pop();
for (int x: G[h]){
if (dis[x] == dis[h] + 1) cnt[x] += cnt[h];
else if (dis[x] > dis[h] + 1){
dis[x] = dis[h] + 1;
cnt[x] = cnt[h];
q.push(x);
}
}
}
for (int i = 1; i <= n; ++i)
if (cnt[i] == m){
printf("YES\n%d\n", i);
return 0;
}
printf("NO\n");
return 0;
}
H High Load Database
题意:给定一个序列,序列中数的和不超过 1 0 6 10^6 106。多次询问,每次给定 t t t,要将序列划分成多个段,每段的和不超过 t t t,求最少段数。
对单个 t t t,可以前缀和加上二分处理。但是多个 t t t,每个 t t t 都这么做会 TLE。
又,对于一个 t t t,序列最多被划分成 O ( 1 0 6 t ) O\left(\frac{10^6}{t}\right) O(t106) 份。因此把所有的 t t t 存下来,对不重复的 t t