Monopoly
按照官方题解所写,本题细节较多,这里我用\(map\)套\(vector<pair<int,int>>\)维护余数,需要注意的是,根据题解所说要找到\(\leq x\)的最大的数且位置最小,所以我对\(pair\)重定义了排序,让第二维按从大到小排序,我的第一维存的是当前同余前缀和的值,第二维才是下标,方便排序。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e17;
int32_t main(int argc, char *argv[]) {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n, m;
cin >> n >> m;
map<int, int> vis;
vector<int> a(n + 1), sum(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
if (!vis[sum[i]]) {
vis[sum[i]] = i;
}
}
if (sum[n] == 0) {
while (m--) {
int x;
cin >> x;
// 对0特判
if (x == 0) {
cout << 0 << '\n';
continue;
}
cout << (vis[x] ? vis[x] : -1) << '\n';
}
}
else {
// 是否需要对后面的数取反
bool rev = false;
if (sum[n] < 0) {
rev = true;
for (int i = 1; i <= n; ++i) {
a[i] = -a[i];
sum[i] = sum[i - 1] + a[i];
}
}
// 用pair方便后面二分查找所以优先将值存到first
// 取模为了安全以及对负数的考虑加上了S
map<int, vector<pair<int, int>>> rem;
for (int i = 1; i <= n; ++i) {
int res = (sum[i] % sum[n] + sum[n]) % sum[n];
rem[res].emplace_back(sum[i], i);
}
// 对每个余数进行排序并加上边界方便后面处理
for (auto& it: rem) {
auto& y = it.second;
y.emplace_back(-INF, 0LL);
sort(y.begin(), y.end(), [&](pair<int, int> A, pair<int, int> B) {
if (A.first == B.first) {
return A.second > B.second;
}
return A.first < B.first;
});
}
while (m--) {
int x;
cin >> x;
if (x == 0) {
cout << 0 << '\n';
continue;
}
if (rev) {
x = -x;
}
int res = (x % sum[n] + sum[n]) % sum[n];
if (rem[res].size() < 1) {
cout << -1 << '\n';
continue;
}
auto& V = rem[res];
// 找到<=x的最大值
auto p = *--upper_bound(V.begin(), V.end(), make_pair(x, INF));
if (p.first == -INF) {
cout << -1 << '\n';
continue;
}
int val = p.first, idx = p.second;
cout << idx + abs(val - x) / sum[n] * n << '\n';
}
}
}
system("pause");
return 0;
}
Jumping Monkey
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
vector<int> e[MAXN], g[MAXN];
void add(int u, int v) {
e[u].push_back(v);
e[v].push_back(u);
}
int fa[MAXN];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
// x <- y
void merge(int x, int y) {
fa[find(y)] = find(x);
}
struct Node {
int idx, val;
bool operator <(const Node& p) const {
return val < p.val;
}
} a[MAXN];
int main(int argc, char *argv[]) {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
fa[i] = i;
e[i].clear();
g[i].clear();
}
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
add(u, v);
}
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
a[i] = {i, x};
}
sort(a + 1, a + n + 1);
vector<int> vis(n + 1), dist(n + 1, 1);
for (int i = 1; i <= n; ++i) {
int u = a[i].idx;
vis[u] = true;
for (int v: e[u]) {
if (vis[v]) {
v = find(v);
g[u].push_back(v);
// cout << u << ' ' << v << '\n';
merge(u, v);
}
}
}
function<void(int)> dfs = [&](int u) -> void {
for (int v: g[u]) {
dist[v] = dist[u] + 1;
dfs(v);
}
};
dfs(a[n].idx);
for (int i = 1; i <= n; ++i) {
cout << dist[i] << '\n';
}
}
system("pause");
return 0;
}