中國大學生程式設計競賽(CCPC)網路選拔賽(重賽)
阿新 • • 發佈:2021-10-13
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; }