Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- */
- #pragma comment(linker, "/STACK:16777216")
- #define _CRT_SECURE_NO_WARNINGS
- #include <fstream>
- #include <iostream>
- #include <string>
- #include <complex>
- #include <math.h>
- #include <set>
- #include <vector>
- #include <map>
- #include <queue>
- #include <stdio.h>
- #include <stack>
- #include <algorithm>
- #include <list>
- #include <ctime>
- #include <memory.h>
- #include <assert.h>
- #define y0 sdkfaslhagaklsldk
- #define y1 aasdfasdfasdf
- #define yn askfhwqriuperikldjk
- #define j1 assdgsdgasghsf
- #define tm sdfjahlfasfh
- #define lr asgasgash
- #define norm asdfasdgasdgsd
- #define eps 1e-9
- #define M_PI 3.141592653589793
- #define bs 1000000007
- #define bsize 350
- using namespace std;
- const int INF = 1e9;
- const int N = 515000;
- using namespace std;
- int n, ar[N];
- int t[N];
- int used[N];
- long long res;
- vector<int> g[N];
- int sum(int r)
- {
- int res = 0;
- for (; r >= 0; r = (r&(r + 1)) - 1)
- res += t[r];
- return res;
- }
- int sum(int l,int r)
- {
- return sum(r) - sum(l - 1);
- }
- void inc(int i, int delta)
- {
- for (; i <N; i = (i | (i + 1)))
- t[i] += delta;
- }
- void dfs(int v)
- {
- used[v] = 1;
- res += sum(ar[v] - 1);
- inc(ar[v], 1);
- for (int i = 0; i < g[v].size(); i++)
- {
- int to = g[v][i];
- if (used[to])
- continue;
- dfs(to);
- }
- inc(ar[v], -1);
- }
- int CNT;
- int done[N];
- int thold;
- long long ans;
- int ans_v;
- int total[N];
- vector<int> ent[N];
- map<pair<int, pair<int, int> >, int> mapp;
- void func(int v)
- {
- done[v] = 1;
- if (ar[v] > thold)
- ++CNT;
- for (int i = 0; i < g[v].size(); i++)
- {
- int to = g[v][i];
- if (done[to])
- continue;
- func(to);
- }
- }
- int count_sub(int v1, int v2, int val)
- {
- CNT = 0;
- thold = val;
- for (int i = 1; i <= n; i++)
- done[i] = 0;
- done[v1] = 1;
- done[v2] = 1;
- func(v2);
- return CNT;
- }
- int smart_sub(int par, int son, int val)
- {
- if (mapp.find(make_pair(val, make_pair(par, son))) != mapp.end())
- return mapp[make_pair(val, make_pair(par, son))];
- return total[val + 1] - mapp[make_pair(val, make_pair(son, par))];
- }
- void trace_solve(int v,long long res)
- {
- used[v] = 1;
- if (res < ans || (res == ans&&v < ans_v))
- {
- ans = res;
- ans_v = v;
- }
- //cout << v << " " << res << endl;
- for (int i = 0; i < g[v].size(); i++)
- {
- int to = g[v][i];
- if (used[to])
- continue;
- long long new_res = res;
- new_res -= total[ar[v] + 1];
- new_res += smart_sub(to, v, ar[v]);// count_sub(to, v, ar[v]);
- new_res += total[ar[to] + 1];
- new_res -= smart_sub(v, to, ar[to]);// count_sub(v, to, ar[to]);
- trace_solve(to, new_res);
- }
- }
- vector<pair<int,int> > queries[N];
- void prec(int v)
- {
- used[v] = 1;
- for (int i = 0; i < g[v].size(); i++)
- {
- int to = g[v][i];
- if (used[to])
- continue;
- prec(to);
- queries[ar[v]].push_back(make_pair(v, to));
- queries[ar[to]].push_back(make_pair(v, to));
- }
- }
- int tin[N], tout[N], timer;
- void build_dfs(int v)
- {
- ++timer;
- tin[v] = timer;
- used[v] = 1;
- for (int i = 0; i < g[v].size(); i++)
- {
- int to = g[v][i];
- if (used[to])
- continue;
- build_dfs(to);
- }
- ++timer;
- tout[v] = timer;
- }
- int main(){
- //freopen("fabro.in","r",stdin);
- //freopen("fabro.out","w",stdout);
- //freopen("F:/in.txt", "r", stdin);
- //freopen("F:/output.txt", "w", stdout);
- //ios_base::sync_with_stdio(0);
- //cin.tie(0);
- cin >> n;
- for (int i = 1; i <= n; i++)
- {
- cin >> ar[i];
- total[ar[i]]++;
- ent[ar[i]].push_back(i);
- }
- for (int i = 1; i < n; i++)
- {
- int a, b;
- cin >> a >> b;
- g[a].push_back(b);
- g[b].push_back(a);
- }
- build_dfs(1);
- for (int i = 0; i <N; i++)
- used[i] = 0;
- prec(1);
- for (int i = 1; i <N; i++)
- used[i] = 0;
- for (int i = n; i; --i)
- {
- for (int j = 0; j < queries[i].size(); j++)
- {
- int vert = queries[i][j].second;
- //cout <<vert<<"%"<< sum(tin[vert], tout[vert]) << endl;
- mapp[make_pair(i, make_pair(queries[i][j].first, queries[i][j].second))] = sum(tin[vert], tout[vert]);
- }
- for (int j = 0; j < ent[i].size(); j++)
- {
- int v = ent[i][j];
- //cout << v<<"@" << tin[v] << endl;
- inc(tin[v], 1);
- }
- }
- for (int i = 0; i < N; i++)
- t[i] = used[i] = 0;
- dfs(1);
- for (int i = n; i; --i)
- total[i] += total[i + 1];
- //cout << res << endl;
- /*for (int i = n; i >=1; i--)
- {
- for (int j = 1; j <= n; j++)
- {
- used[j] = 0;
- }
- for (int j = 0; j <= n; j++)
- {
- t[j] = 0;
- }
- res = 0;
- dfs(i);
- cout << "!"<<i << " " << res << endl;
- }
- */
- ans = res;
- ans_v = 1;
- for (int i = 0; i <N; i++)
- used[i] = 0, t[i] = 0;
- for (int i = 0; i <N; i++)
- used[i] = 0,
- t[i] = 0;
- trace_solve(1,res);
- cout << ans_v << " " << ans << endl;
- cin.get(); cin.get();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement