이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,fma")
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
#define MAX 202020
#define MAXS 20
#define INF 1000000000000000001
#define bb ' '
#define ln '\n'
#define Ln '\n'
pii edges[MAX];
vector<pii> toggle[MAX];
int laston[MAX];
vector<int> adj[MAX];
int ans[MAX];
int vis[MAX];
int num[MAX];
map<int, int> mp[MAX];
int findnxt(int v, int e) { return edges[e].first + edges[e].second - v; }
map<int, int> mpall;
int mpsum;
void bottomup(int x, int p = 0, int isrt = 0) {
mp[x].clear();
mp[x][0] = 1;
int i;
for (auto e : adj[x]) {
int v = findnxt(x, e);
if (vis[v] || v == p) continue;
if (toggle[e].empty()) continue;
bottomup(v, x);
for (i = 0; i < toggle[e].size(); i++) {
int s;
if (i) s = toggle[e][i - 1].second;
else s = -1;
int nxt = toggle[e][i].first;
while (1) {
auto it = mp[v].lower_bound(s);
if (it == mp[v].end()) break;
if (it->first >= nxt) break;
mp[v][nxt] += it->second;
mp[v].erase(it);
}
}
while (mp[v].size() && mp[v].rbegin()->first >= toggle[e].back().second) mp[v].erase(mp[v].rbegin()->first);
if (!isrt) {
if (mp[v].size() > mp[x].size()) swap(mp[v], mp[x]);
for (auto& [a, b] : mp[v]) mp[x][a] += b;
}
}
}
void topdown(int x, int p, int mul) {
ans[x] += mpsum * mul;
int i;
for (auto e : adj[x]) {
int v = findnxt(x, e);
if (vis[v] || v == p) continue;
if (toggle[e].empty()) continue;
vector<pii> logv;
for (i = 0; i < toggle[e].size(); i++) {
int s;
if (i) s = toggle[e][i - 1].second;
else s = -1;
int nxt = toggle[e][i].first;
while (1) {
auto it = mpall.lower_bound(s);
if (it == mpall.end()) break;
if (it->first >= nxt) break;
logv.emplace_back(it->first, it->second);
logv.emplace_back(nxt, -it->second);
mpall[nxt] += it->second;
mpall.erase(it);
}
}
while (mpall.size() && mpall.rbegin()->first >= toggle[e].back().second) {
mpsum -= mpall.rbegin()->second;
logv.emplace_back(mpall.rbegin()->first, mpall.rbegin()->second);
mpall.erase(mpall.rbegin()->first);
}
topdown(v, x, mul);
for (auto& [a, b] : logv) {
mpall[a] += b, mpsum += b;
if (!mpall[a]) mpall.erase(a);
}
}
}
void make_num(int x, int p = 0) {
mp[x].clear();
num[x] = 1;
for (auto e : adj[x]) {
int v = findnxt(x, e);
if (v == p || vis[v]) continue;
make_num(v, x);
num[x] += num[v];
}
}
void make_tree(int x) {
make_num(x);
int c = x;
int n = num[x];
while (1) {
int changed = 0;
for (auto e : adj[c]) {
int v = findnxt(c, e);
if (!vis[v] && num[v] < num[c]) {
if (num[v] > n / 2) {
c = v;
changed = 1;
break;
}
}
}
if (!changed) break;
}
bottomup(c, 0, 1);
mpall.clear();
mpsum = 0;
for (auto e : adj[c]) {
int v = findnxt(c, e);
if (vis[v]) continue;
for (auto& [a, b] : mp[v]) if (b) mpall[a] += b, mpsum += b;
}
for (auto& [a, b] : mp[c]) if (b) mpall[a] += b, mpsum += b;
ans[c] += mpsum;
int i;
for (auto e : adj[c]) {
int v = findnxt(c, e);
if (vis[v]) continue;
if (toggle[e].empty()) continue;
vector<pii> logv;
for (i = 0; i < toggle[e].size(); i++) {
int s;
if (i) s = toggle[e][i - 1].second;
else s = -1;
int nxt = toggle[e][i].first;
while (1) {
auto it = mpall.lower_bound(s);
if (it == mpall.end()) break;
if (it->first >= nxt) break;
logv.emplace_back(it->first, it->second);
logv.emplace_back(nxt, -it->second);
mpall[nxt] += it->second;
mpall.erase(it);
}
}
while (mpall.size() && mpall.rbegin()->first >= toggle[e].back().second) {
mpsum -= mpall.rbegin()->second;
logv.emplace_back(mpall.rbegin()->first, mpall.rbegin()->second);
mpall.erase(mpall.rbegin()->first);
}
topdown(v, c, 1);
for (auto& [a, b] : logv) {
mpall[a] += b, mpsum += b;
if (!mpall[a]) mpall.erase(a);
}
}
for (auto e : adj[c]) {
int v = findnxt(c, e);
if (vis[v]) continue;
if (toggle[e].empty()) continue;
mpsum = 0;
for (auto& [a, b] : mp[v]) mpsum += b;
swap(mpall, mp[v]);
topdown(v, c, -1);
}
vis[c] = 1;
for (auto e : adj[c]) {
int v = findnxt(c, e);
if (!vis[v]) make_tree(v);
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
int N, M, Q;
cin >> N >> M >> Q;
int i, a, b;
for (i = 1; i < N; i++) {
cin >> a >> b;
edges[i] = pii(a, b);
adj[a].push_back(i);
adj[b].push_back(i);
}
for (i = 1; i <= M; i++) {
cin >> a;
if (laston[a]) {
toggle[a].emplace_back(laston[a], i);
laston[a] = 0;
}
else laston[a] = i;
}
for (i = 1; i < N; i++) if (laston[i]) toggle[i].emplace_back(laston[i], M + 1);
make_tree(1);
vector<int> qs;
while (Q--) {
cin >> a;
qs.push_back(a);
}
for (auto v : qs) cout << ans[v] << ln;
}
컴파일 시 표준 에러 (stderr) 메시지
synchronization.cpp: In function 'void bottomup(int, int, int)':
synchronization.cpp:36:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
36 | for (i = 0; i < toggle[e].size(); i++) {
| ~~^~~~~~~~~~~~~~~~~~
synchronization.cpp: In function 'void topdown(int, int, int)':
synchronization.cpp:64:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
64 | for (i = 0; i < toggle[e].size(); i++) {
| ~~^~~~~~~~~~~~~~~~~~
synchronization.cpp: In function 'void make_tree(int)':
synchronization.cpp:135:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
135 | for (i = 0; i < toggle[e].size(); i++) {
| ~~^~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |