Submission #1349927

#TimeUsernameProblemLanguageResultExecution timeMemory
1349927retardeCat Exercise (JOI23_ho_t4)C++20
100 / 100
155 ms78564 KiB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define int long long
#define all(x) (x).begin(), (x).end()

typedef long double ld;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vector<int>> vvi;
typedef vector<vector<bool>> vvb;
typedef vector<vector<ll>> vvll;
typedef vector<string> vs;
typedef vector<vector<string>> vvs;
typedef vector<char> vc;
typedef vector<vector<char>> vvc;
typedef map<int, int> mii;
typedef unordered_map<int, int> umii;

const int mod = 1e9 + 7;
const int inf = INTMAX_MAX;
const bool tc = false;

int n; const int mxn = 2e5+5, LG = 20;
int p[mxn]; vi adj[mxn], adj2[mxn];
int dep[mxn], up[mxn][LG];

class DisjointSets {
  private:
	vector<int> parents;
	vector<int> sizes;
    vector<pii> mx;

  public:
	DisjointSets(int size) : parents(size), sizes(size, 1), mx(size) {
		for (int i = 0; i < size; i++) { parents[i] = i; mx[i] = {p[i], i}; }
	}

	/** @return the "representative" node in x's component */
	int find(int x) { return parents[x] == x ? x : (parents[x] = find(parents[x])); }

	/** @return whether the merge changed connectivity */
	bool unite(int x, int y) {
		int x_root = find(x);
		int y_root = find(y);
		if (x_root == y_root) { return false; }

		if (sizes[x_root] < sizes[y_root]) { swap(x_root, y_root); }
		sizes[x_root] += sizes[y_root];
		parents[y_root] = x_root;

        pii z = max(mx[x_root], mx[y_root]);
        mx[x_root] = mx[y_root] = z;

		return true;
	}

	/** @return whether x and y are in the same connected component */
	bool connected(int x, int y) { return find(x) == find(y); }

    pii top(int u) { return mx[find(u)]; }
};

void dfsl(int u, int par) {
    up[u][0] = par;
    for (int j = 1; j < LG; j++) {
        up[u][j] = up[up[u][j - 1]][j - 1];
    }
    for (int v : adj[u]) {
        if (v == par) continue;
        dep[v] = dep[u] + 1;
        dfsl(v, u);
    }
}

void build() {
    dep[0] = 0;
    dfsl(0, 0);
}

int lca(int u, int v) {
    if (dep[u] < dep[v]) swap(u, v);
    int d = dep[u] - dep[v];
    for (int j = LG - 1; j >= 0; j--) {
        if (d & (1 << j)) u = up[u][j];
    }
    if (u == v) return u;
    for (int j = LG - 1; j >= 0; j--) {
        if (up[u][j] != up[v][j]) {
            u = up[u][j];
            v = up[v][j];
        }
    }
    return up[u][0];
}

int dist(int u, int v) {
    int w = lca(u, v);
    return dep[u] + dep[v] - 2 * dep[w];
}

int ans = -1;
void ansdfs(int node, int prev, int d) {
    ans = max(ans, d);
    for (auto &neighbour : adj2[node]) {
        if (neighbour == prev) continue;
        ansdfs(neighbour, node, d + dist(neighbour,node));
    }
}  

inline void solve() {
    cin >> n; vector<pii> tp; int s = -1;
    for (int i = 0; i < n; i++) {cin >> p[i]; tp.pb({p[i], i}); if (p[i] == n) s = i;}
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        u--; v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    sort(all(tp)); build();

    DisjointSets dsu(n);
    for (auto &x : tp) {
        int v = x.fi; int node = x.se;
        for (auto &neighbour : adj[node]) {
            if (p[neighbour]>p[node]) continue;
            pii z = dsu.top(neighbour);
            adj2[node].pb(z.se);
            adj2[z.se].pb(node);
        }
        for (auto &neighbour : adj[node]) {
            if (p[neighbour]<p[node]) dsu.unite(node, neighbour);
        }
    }

    ans = -1; ansdfs(s, -1, 0);
    cout << ans << '\n';
}

void setIO(string s) {
    freopen((s + ".in").c_str(), "r", stdin);
    freopen((s + ".out").c_str(), "w", stdout);
}

signed main() {
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    //setIO();

    int t = 1;
    if (tc) {
        cin >> t;
    }

    while (t--) {
        solve();
    }
}

Compilation message (stderr)

Main.cpp: In function 'void setIO(std::string)':
Main.cpp:151:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  151 |     freopen((s + ".in").c_str(), "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:152:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  152 |     freopen((s + ".out").c_str(), "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...