Original link: https://www.shuizilong.com/house/archives/spoj-twopaths-two-paths/

Question: Find the maximum value of the product of two disjoint paths.
Analysis: The dfs order maintains diameter has a very nice property. . . That is, you can find the diameter inside the subtree and the diameter outside the subtree. . So we only need to do dfs again, and then multiply the two diameters every time the query comes out. . It’s a pity that O(nlogn) may not be able to pass big data. . .
#include <lastweapon/io>
using namespace lastweapon;
const int N = int(1e5) + 9;
int L[N], R[N], dep[N], id[N], nn;
VI adj[N]; int n;
struct rec{
int d, dd, ld, rd, D;
void init(LL _d, LL _dd) {
d = _d; dd = 2*_dd;
D = ld = -INF; rd = _d - dd;
}
} T[N*4];
// max d[l] + d[r] - dd[m]
// l < m <= r
// d depth // dd father's depth #define lx (x<<1)
#define rx(lx|1)
#define ml ((l+r)>>1)
#define mr (ml+1)
#define lc lx,l,ml
#define rc rx,mr,r
void upd(int x) {
T[x].d = max(T[lx].d, T[rx].d);
T[x].dd = min(T[lx].dd, T[rx].dd);
T[x].ld = max(T[lx].ld, T[rx].ld, T[lx].d - T[rx].dd);
T[x].rd = max(T[lx].rd, T[rx].rd, T[rx].d - T[lx].dd);
T[x].D = max(T[lx].D, T[rx].D, T[lx].ld + T[rx].d, T[lx].d + T[rx].rd );
}
rec upd(rec l, rec r) {
rec x;
xd = max(ld, rd);
x.dd = min(l.dd, r.dd);
x.ld = max(l.ld, r.ld, ld - r.dd);
x.rd = max(l.rd, r.rd, rd - l.dd);
xD = max(lD, rD, l.ld + rd, ld + r.rd);
return x;
}
void Build(int x, int l, int r) {
if (l == r) {
T[x].init(dep[id[l]], dep[id[l]]-1);
} else {
Build(lc);
Build(rc);
upd(x);
}
}
void dfs(int u = 1, int p = 0) {
id[L[u] = ++nn] = u;
for (auto v: adj[u]) if (v != p) {
dep[v] = dep[u] + 1;
dfs(v, u);
}
R[u] = nn;
}
rec Query(int x, int l, int r, int a, int b) {
/*if (b < l || r < a) {
rec x; x.init(-INF,INF);
return x;
}*/
if (a <= l && r <= b) {
return T[x];
} else {
if (b < mr) return Query(lc, a, b);
if (ml < a) return Query(rc, a, b);
return upd(Query(lc, a, b), Query(rc, a, b));
}
}
LL z = 0;
void gao(int u = 1, int p = 0) {
for (auto v: adj[u]) if (v != p) {
LL D = Query(1,1,n,L[v],R[v]).D;
checkMax(z, D * upd(Query(1,1,n,1,L[v]-1), Query(1,1,n,R[v]+1,n)).D);
/*cout << L[v] << " " << R[v] << " " " << v << " " << Query(1,1,n,L[v],R[v]) .D << " " <<
upd(Query(1,1,n,1,L[v]-1), Query(1,1,n,R[v]+1,n)).D
<< " " << z << endl;*/
gao(v, u);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
dep[0] = INF;
DO(RD(n)-1) {
int x, y; RD(x, y);
adj[x].PB(y);
adj[y].PB(x);
}
if (n > 3) {
dfs(); Build(1, 1, n); gao();
}
cout << z << endl;
}
This article is transferred from: https://www.shuizilong.com/house/archives/spoj-twopaths-two-paths/
This site is only for collection, and the copyright belongs to the original author.