#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3")
#define endl '\n'
#define db double
#define ll __int128
#define int long long
#define pb push_back
#define fs first
#define sd second
#define Mod long(1e9 + 7)
#define all(x) x.begin(), x.end()
#define unvisited long(-1)
#define Eps double(1e-9)
#define _for(i, n) for(int i = 0; i < (n); i++)
#define dbg(x) cout << #x ": " << x << endl;
const int Max = 1e6 + 7, Inf = 1e9 + 7;
void print(bool x) { cout << (x ? "YES" : "NO") << endl; }
string tostring (__int128 x)
{
string ans = "";
while(x > 0)
{
ans += (x % 10 + '0');
x /= 10;
}
reverse(all(ans));
return ans;
}
vector <vector<int>> v;
vector <int> in, out, s;
struct SegmentTree1
{
vector <int> tree; int l;
void update(int k, int x){
k += (l - 1)+1; tree[k] = x;
for(k /= 2; k > 0; k /= 2){
tree[k] = max(tree[2*k], tree[2*k+1]);
}
}
int query(int node, int x, int y, int s, int e){
if(s > y || e < x) return 0;
if(s >= x && e <= y){
return tree[node];
}
int mid = (s + e) / 2;
return max(query(node*2, x, y, s, mid),
query(node*2+1, x, y, mid+1, e));
}
int query(int x, int y){
return query(1, x+1, y+1, 1, l);
}
SegmentTree1 (int n)
{
for(l = 1; l < n; l *= 2);
tree.assign(2*l+7, 0);
}
};
struct SegmentTree2
{
vector <int> tree; int l;
void update(int k, int x){
k += (l - 1) + 1; tree[k] = x;
for(k /= 2; k > 0; k /= 2){
tree[k] = tree[2*k] + tree[2*k+1];
}
}
int query(int node, int x, int y, int s, int e){
if(s > y || e < x) return 0;
if(s >= x && e <= y){
return tree[node];
}
int mid = (s + e) / 2;
return query(node*2, x, y, s, mid) +
query(node*2+1, x, y, mid+1, e);
}
int query(int x, int y){
return query(1, x+1, y+1, 1, l);
}
SegmentTree2 (int n)
{
for(l = 1; l < n; l *= 2);
tree.assign(2*l+7, 0);
}
};
void dfs(int node)
{
in[node] = s.size();
s.push_back(node);
for(auto& u : v[node]){
dfs(u);
}
out[node] = s.size();
s.push_back(node);
}
vector <int> cmp(vector <int> c){
vector <pair<int, int>> t;
_for(i, c.size()) t.push_back({ c[i], i });
sort(all(t));
_for(i, c.size()) c[t[i].sd] = i;
return c;
}
void solve()
{
int n; cin >> n;
vector <int> c(n+1), d(n+1);
_for(i, n) cin >> c[i+1];
c = cmp(c);
vector <pair<int, int>> edge(n-1);
v.assign(n+1, vector <int> ());
for(auto& u : edge){
cin >> u.fs >> u.sd;
v[u.fs].pb(u.sd); //v[u.sd].pb(u.fs);
}
in.assign(2*n+7, 0);
out.assign(2*n+7, 0);
dfs(1);
vector <vector<int>> p(n+1, vector <int> (21, 0));
SegmentTree1 St1(2*n+7); SegmentTree2 St2(2*n+7);
_for(i, n-1)
{
vector <pair<int, int>> f;
int ans = 0, x = edge[i].fs;
if(i == 1){
ans = (c[edge[i].fs] > c[edge[i].sd]);
}
while (x != 0)
{
f.push_back({ 1, St1.query(in[x], out[x]) });
for(int j = 20; j >= 0; j--) if(p[x][j] != 0){
int y = p[x][j];
if(St1.query(in[y], out[y]) == f.back().sd){
x = y;
f.back().fs += (1LL << j);
}
}
x = p[x][0];
}
p[edge[i].sd][0] = edge[i].fs;
for(int j = 1; j <= 20; j++){
p[edge[i].sd][j] = p[p[edge[i].sd][j-1]][j-1];
}
reverse(all(f));
for(auto& u : f){
ans = ans + u.fs * (St2.query(c[edge[u.sd].sd]+1, n+2));
St2.update(c[edge[u.sd].sd], u.fs);
}
for(auto& u : f){
St2.update(c[edge[u.sd].sd], 0);
}
St1.update(in[edge[i].sd], i);
cout << ans << endl;
}
}
int32_t main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int Q = 1; //cin >> Q;
while (Q--)
{
solve();
}
return 0;
}
Compilation message
construction.cpp: In function 'std::vector<long long int> cmp(std::vector<long long int>)':
construction.cpp:16:37: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
16 | #define _for(i, n) for(int i = 0; i < (n); i++)
| ^
construction.cpp:115:5: note: in expansion of macro '_for'
115 | _for(i, c.size()) t.push_back({ c[i], i });
| ^~~~
construction.cpp:16:37: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
16 | #define _for(i, n) for(int i = 0; i < (n); i++)
| ^
construction.cpp:117:5: note: in expansion of macro '_for'
117 | _for(i, c.size()) c[t[i].sd] = i;
| ^~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Incorrect |
1 ms |
348 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Incorrect |
1 ms |
348 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
0 ms |
348 KB |
Output is correct |
3 |
Correct |
0 ms |
348 KB |
Output is correct |
4 |
Incorrect |
1 ms |
348 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |