이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
struct Data {
int from, to, color;
Data(int from = 0,int to = 0,int color = 0) : from(from), to(to), color(color) {}
};
int n;
vector<int> g[N];
int from[N], to[N], color[N];
int child[N], nxt[N], root[N];
int par[N], pos[N], ft[N];
deque<Data> dq[N];
void add(int p,int x) { for (; p <= n; p += p & -p) ft[p] += x; }
int get(int p) { int ans = 0; for (; p > 0; p -= p & -p) ans += ft[p]; return ans; }
void dfs(int u) {
child[u] = 1;
for (int v : g[u]) {
par[v] = u;
dfs(v);
child[u] += child[v];
}
}
void hld(int u,int root) {
::root[u] = root;
if (u == root) pos[u] = 1;
int nxt = 0;
for (int v : g[u]) {
if (child[v] > child[nxt]) nxt = v;
}
if (nxt) {
pos[nxt] = pos[u] + 1;
hld(nxt, root);
}
for (int v : g[u]) if (v != nxt) {
hld(v, v);
}
}
void get_hld(int u) {
long long ans = 0;
vector< pair<int, int> > change;
while (u) {
int p = pos[u];
u = root[u];
int ptr = 0;
while (ptr < dq[u].size() && dq[u][ptr].from <= p) ptr++;
ptr--;
for (int i = ptr; i >= 0; --i) {
int cnt = min(p, dq[u][i].to) - dq[u][i].from + 1;
ans += (long long) cnt * get(dq[u][i].color - 1);
add(dq[u][i].color, cnt);
change.push_back({dq[u][i].color, cnt});
}
u = par[u];
}
for (auto p : change) add(p.first, -p.second);
printf("%lld\n", ans);
}
void upd_hld(int u,int color) {
while (u) {
int p = pos[u];
u = root[u];
while (dq[u].size()) {
if (dq[u][0].to <= p) dq[u].pop_front();
else { dq[u][0].from = p + 1; break; }
}
dq[u].push_front(Data(1, p, color));
u = par[u];
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", color + i);
}
{
vector<int> comp;
for (int i = 1; i <= n; ++i) comp.push_back(color[i]);
sort(comp.begin(), comp.end());
comp.resize(unique(comp.begin(), comp.end()) - comp.begin());
for (int i = 1; i <= n; ++i) color[i] = lower_bound(comp.begin(), comp.end(), color[i]) - comp.begin() + 1;
}
for (int i = 1; i < n; ++i) {
scanf("%d %d", from + i, to + i);
g[from[i]].push_back(to[i]);
}
dfs(1);
hld(1, 1);
for (int i = 1; i < n; ++i) {
get_hld(from[i]);
upd_hld(to[i], color[to[i]]);
}
}
컴파일 시 표준 에러 (stderr) 메시지
construction.cpp: In function 'void get_hld(int)':
construction.cpp:54:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while (ptr < dq[u].size() && dq[u][ptr].from <= p) ptr++;
~~~~^~~~~~~~~~~~~~
construction.cpp: In function 'int main()':
construction.cpp:84:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", &n);
~~~~~^~~~~~~~~~
construction.cpp:86:12: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", color + i);
~~~~~^~~~~~~~~~~~~~~~~
construction.cpp:96:12: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d", from + i, to + 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... |