Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- //#include <ext/pb_ds/detail/standard_policies.hpp>
- //#include <ext/pb_ds/assoc_container.hpp>
- //#include <ext/pb_ds/tree_policy.hpp>
- #define pb push_back
- #define F first
- #define S second
- #define ll long long
- #define ld long double
- #define endl '\n'
- #define TIME 1.0*clock()/CLOCKS_PER_SEC
- #define null NULL
- using namespace std;
- //using namespace __gnu_pbds;
- //typedef tree <pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
- mt19937 gen(chrono::system_clock::now().time_since_epoch().count());
- const int M = 1e9 + 7;
- const int FFTM = 998244353;
- const int N = 2e5 + 7;
- struct segtree{
- int tn = 1;
- vector<int> t;
- segtree(){}
- segtree(int n){
- tn = 1;
- while (tn < n) tn <<= 1;
- t.resize(tn<<1|1, -1e9 - 7);
- }
- resize(int n){
- tn = 1;
- while (tn < n) tn <<= 1;
- t.assign(tn<<1|1, -1e9 - 7);
- }
- void clear(){
- t.assign(t.size(), -1e9 - 7);
- }
- void upd(int v, int tl, int tr, int p, int x){
- if (tr - tl == 1){
- t[v] = max(t[v], x);
- return;
- }
- int m = (tl + tr)>>1;
- if (p < m) upd(v<<1, tl, m, p, x);
- else upd(v<<1|1, m, tr, p, x);
- t[v] = max(t[v<<1], t[v<<1|1]);
- }
- void upd(int p, int x){
- upd(1, 0, tn, p, x);
- }
- int q(int v, int tl, int tr, int l, int r){
- if (tr <= l || r <= tl) return -1e9 - 7;
- if (l <= tl && tr <= r) return t[v];
- int m = (tl + tr)>>1;
- return max(q(v<<1, tl, m, l, r), q(v<<1|1, m, tr, l, r));
- }
- int q(int l, int r){
- return q(1, 0, tn, l, r);
- }
- };
- int n, sz[N], U[N], x[N], p, a, b, VV;
- vector<int> now, g[N];
- segtree t;
- ll res = -1;
- int Pos(int x){
- int p = upper_bound(now.begin(), now.end(), x) - now.begin();
- return p - 1;
- }
- void calc(int v, int p){
- sz[v] = 1;
- for (auto to : g[v])
- if (to != p && !U[to]) calc(to, v), sz[v] += sz[to];
- }
- int Find(int v, int p, int k){
- for (auto to : g[v])
- if (to != p && !U[to] && sz[to] >= k) return Find(to, v, k);
- return v;
- }
- void upd(int v, int p, int d = 1){
- t.upd(Pos(x[v]), d);
- for (auto to : g[v])
- if (to != p && !U[to]) upd(to, v, d + 1);
- }
- void solve(int v, int p, int d = 1){
- res = max(res, 1ll*(1ll*t.q(Pos(x[v]), now.size()) + d)*x[v]);
- for (auto to : g[v])
- if (to != p && !U[to]) solve(to, v, d + 1);
- }
- void P(int v, int p, vector<int> &A){
- A.pb(x[v]);
- for (auto to : g[v])
- if (to != p && !U[to]) P(to, v, A);
- }
- void go(int v){
- calc(v, v);
- int V = Find(v, v, sz[v]/2);VV = V;
- vector<int> all;
- P(V, V, all);
- sort(all.begin(), all.end());
- all.resize(distance(all.begin(), unique(all.begin(), all.end())));
- now = all;
- t.resize(all.size() + 1);
- for (int i = 0; i < g[V].size(); i++){
- int to = g[V][i];
- if (U[to]) continue;
- solve(to, V);
- upd(to, V);
- }
- t.clear();
- for (int i = g[V].size() - 1; i >= 0; i--){
- int to = g[V][i];
- if (U[to]) continue;
- solve(to, V);
- upd(to, V);
- }
- U[V] = 1;
- for (auto to : g[V])
- if (!U[to]) go(to);
- }
- int main() {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #else
- freopen("tree.in", "r", stdin);
- freopen("tree.out", "w", stdout);
- #endif // LOCAL
- cin >> n;
- for (int i = 0; i < n; i++) cin >> x[i];
- for (int i = 1; i < n; i++) cin >> a >> b, a--, b--, g[a].pb(b), g[b].pb(a);
- go(0);
- cout << res;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement