#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pli pair<ll, int>
#define debug(x) cout << #x << " = " << x << '\n'
#define all(a) a.begin(), a.end()
#define SZ(a) (int)(a).size()
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
const ll inf64 = 3e18;
const int inf32 = 2e9 + 5;
struct FenwickTree {
int n;
vector<int> node, his;
FenwickTree() {}
void init(int _n) {
n = _n;
node.assign(n + 3, 0);
}
void upd(int i, int x) {
for(; i <= n; i += i & (-i)) {
node[i] += x;
his.push_back(i);
}
}
int get(int i) {
int res = 0;
for(; i; i -= i & (-i))
res += node[i];
return res;
}
void reset() {
for(int i : his)
node[i] = 0;
his.clear();
}
};
FenwickTree fen;
int n, a[N];
vector<int> g[N];
vector<pii> edges;
void compress() {
pii b[n + 3];
for(int i = 1; i <= n; i++)
b[i] = make_pair(a[i], i);
sort(b + 1, b + 1 + n);
for(int i = 1, id = 0; i <= n; i++) {
id += i == 1 || b[i].fi != b[i - 1].fi;
a[b[i].se] = id;
}
}
int h[N], par[N], hev[N], head[N];
vector<pii> dat[N];
bool exist[N];
int dfs_tree(int u) {
int sz = 1, mx = 0;
for(int v : g[u]) {
par[v] = u, h[v] = h[u] + 1;
int szc = dfs_tree(v);
sz += szc;
if(szc > mx) mx = szc, hev[u] = v;
}
return sz;
}
void decompose(int u, int top) {
head[u] = top;
if(hev[u]) decompose(hev[u], top);
for(int v : g[u])
if(v != hev[u]) decompose(v, v);
}
void update(int u, int x) {
while(u) {
int v = head[u], c;
while(SZ(dat[v]) && h[dat[v].back().se] <= h[u]) {
c = dat[v].back().fi;
dat[v].pop_back();
}
if(SZ(dat[v])) {
if(dat[v].back().se != hev[u]) dat[v].push_back({c, hev[u]});
}
else {
if(exist[hev[u]]) dat[v].push_back({c, hev[u]});
}
dat[v].push_back({x, v});
u = par[v];
}
}
ll query(int u) {
int U = u;
vector<pii> vec;
while(u) {
int v = head[u];
vector<pii> tmp;
for(int i = SZ(dat[v]) - 1; i >= 0; i--) {
if(h[dat[v][i].se] > h[u]) break;
tmp.push_back(dat[v][i]);
}
for(int i = SZ(tmp) - 1; i >= 0; i--)
vec.push_back(tmp[i]);
u = par[v];
}
ll ans = 0;
for(int i = 0; i < SZ(vec); i++) {
pii p = vec[i];
int cnt = h[U] - h[p.se] + (i == 0);
ans += 1ll * cnt * fen.get(p.fi - 1);
fen.upd(p.fi, cnt);
U = p.se;
}
fen.reset();
return ans;
}
void solve() {
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
compress();
for(int i = 1, u, v; i < n; i++) {
cin >> u >> v;
g[u].push_back(v);
edges.push_back({u, v});
}
dfs_tree(1);
decompose(1, 1);
fen.init(n);
dat[1].push_back({a[1], 1});
exist[1] = true;
for(pii e : edges) {
int u, v;
tie(u, v) = e;
exist[v] = true;
cout << query(u) << '\n';
update(v, a[v]);
}
}
int main() {
auto start = chrono::steady_clock::now();
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if(fopen("input.txt", "r")) {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
}
int test = 1;
// cin >> test;
while(test--) solve();
chrono::duration<double> elapsed {chrono::steady_clock::now() - start};
cerr << "\n>> Runtime: " << elapsed.count() << "s\n";
}
Compilation message (stderr)
construction.cpp: In function 'int main()':
construction.cpp:173:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
173 | freopen("input.txt", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
construction.cpp:174:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
174 | freopen("output.txt", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |