#include <bits/stdc++.h>
#define task "BriantheCrab"
#define int long long
#define pii pair <int, int>
#define fi first
#define se second
#define szf sizeof
#define sz(s) (int)((s).size())
#define all(v) (v).begin(), (v).end()
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
using namespace std;
template <class T> void minimize (T &t, T f) {if (t > f) t = f;}
template <class T> void maximize (T &t, T f) {if (t < f) t = f;}
const int maxN = 1e6 + 5;
const int inf = 1e18 + 7;
const int mod = 1e9 + 7;
// khong tu code thi khong kha len duoc dau
struct Fenwick {
int bit[maxN];
inline void upd (int id, int val) {
for (; id < maxN; id += id & (-id)) {
bit[id] += val;
}
}
inline int get (int id) {
int res = 0;
for (; id; id -= id & (-id)) {
res += bit[id];
}
return res;
}
};
int n;
int c[maxN], res[maxN];
vector <int> adj[maxN];
int par[maxN];
int height[maxN];
int head[maxN], pos[maxN], sz[maxN];
int timer = 0;
vector <pii> q, st[maxN], cur;
pii a[maxN], b[maxN];
Fenwick T;
void dfs (int u, int p) {
sz[u] = 1;
for (auto v : adj[u]) {
if (v == p) {
continue;
}
height[v] = height[u] + 1;
dfs (v, u);
sz[u] += sz[v];
}
}
void HLD (int u, int p, int h) {
pos[u] = ++timer;
head[u] = h;
if (sz (adj[u]) == 1 && u != 1) {
return;
}
int nxt = 0, curMax = 0;
for (auto v : adj[u]) {
if (v == p) {
continue;
}
if (curMax < sz[v]) {
curMax = sz[v];
nxt = v;
}
}
HLD (nxt, u, h);
for (auto v : adj[u]) {
if (v != nxt && v != p) {
HLD (v, u, v);
}
}
}
bool cmp (pii A, pii B) {
return A.se < B.se;
}
int calInv () {
int n = sz (cur);
if (n == 0) {
return 0;
}
sort (all (cur), cmp);
// cout << "bruh " << n << '\n';
// cout << "all ";
// for (auto it : cur) {
// cout << it.fi << ' ' << it.se << ' ';
// }
// cout << '\n';
int j = 1;
b[1] = cur[0];
for (int i = 1; i < n; i ++) {
if (cur[i].se == cur[i - 1].se) {
b[j].fi = cur[i].fi;
}
else {
j ++;
b[j] = cur[i];
}
}
n = j;
// for (int i = 1; i <= n; i ++) {
// cout << "skibidi " << b[i].fi << ' ' << b[i].se << '\n';
// }
for (int i = 1; i <= n; i ++) {
a[i].fi = b[i].fi;
if (i == 1) {
a[i].se = b[i].se + 1;
}
else {
a[i].se = b[i].se - b[i - 1].se;
}
//if (n == 2) cout << a[i].fi << ' ' << a[i].se << '\n';
}
int res = 0;
for (int i = 1; i <= n; i ++) {
res += (T.get (maxN - 1) - T.get (a[i].fi)) * a[i].se;
//cout << T.get (a[i].fi + 1) << ' ' << a[i].fi << ' ' << a[i].se << '\n';
T.upd (a[i].fi, a[i].se);
}
for (int i = 1; i <= n; i ++) {
T.upd (a[i].fi, -a[i].se);
}
return res;
}
void updPath (int curNode, int val) {
vector <pii> tmp;
while (!st[head[curNode]].empty () && st[head[curNode]].back ().se <= height[curNode]) {
auto [v, h] = st[head[curNode]].back ();
tmp.push_back ({v, h});
st[head[curNode]].pop_back ();
}
if (!st[head[curNode]].empty ()) {
auto [v, h] = st[head[curNode]].back ();
// if (v == 2) {
// cout << "wtf " << '\n';
// }
tmp.push_back ({st[head[curNode]].back ().fi, height[curNode]});
}
st[head[curNode]].push_back ({val, height[curNode]});
while (!tmp.empty ()) {
cur.push_back (tmp.back ());
tmp.pop_back ();
}
if (par[head[curNode]] != 0) {
updPath (par[head[curNode]], val);
}
return;
}
void solve () {
cin >> n;
vector <int> zip;
for (int i = 1; i <= n; i ++) {
cin >> c[i];
zip.push_back (c[i]);
}
sort (all (zip));
zip.erase (unique (all (zip)), zip.end ());
for (int i = 1; i <= n; i ++) {
c[i] = lower_bound (all (zip), c[i]) - zip.begin () + 1;
//cout << c[i] << ' ';
}
//cout << '\n';
for (int i = 1; i <= n - 1; i ++) {
int u, v;
cin >> u >> v;
q.push_back ({u, v});
par[v] = u;
adj[u].push_back (v);
adj[v].push_back (u);
}
dfs (1, 1);
HLD (1, 1, 1);
for (auto [u, v] : q) {
cur.clear ();
//cout << v << ' ' << c[v] << '\n';
updPath (v, c[v]);
cout << calInv () << '\n';
}
return;
}
signed main () {
cin.tie (nullptr) -> sync_with_stdio (false);
if (fopen (task".inp", "r")) {
freopen (task".inp", "r", stdin);
freopen (task".out", "w", stdout);
}
int t = 1;
//cin >> t;
while (t --) {
solve ();
}
return 0;
}
// thfv
Compilation message (stderr)
construction.cpp: In function 'int main()':
construction.cpp:207:17: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
207 | freopen (task".inp", "r", stdin);
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
construction.cpp:208:17: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
208 | freopen (task".out", "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... |