# 【做题】51Nod1766树上的最远点对——直径&线段树

$n,m \leq 10^5$

#include <bits/stdc++.h>
using namespace std;
#define gc() getchar()
template <typename tp>
x = 0; char tmp; bool key = 0;
for (tmp = gc() ; !isdigit(tmp) ; tmp = gc())
key = (tmp == '-');
for ( ; isdigit(tmp) ; tmp = gc())
x = (x << 3) + (x << 1) + tmp - '0';
if (key) x = -x;
}
const int N = 100010, MP = 19;
struct edge {
int la,b,v;
} con[N << 1];
int tot,fir[N],n,m;
void add(int from,int to,int val) {
con[++tot] = (edge) {fir[from],to,val};
fir[from] = tot;
}
int dep[N],dfn[N << 1],dcnt,mn[N << 1][MP],ln[N << 1],rec[N],dis[N];
int lca(int x,int y) {
x = rec[x], y = rec[y];
if (x > y) swap(x,y);
int len = ln[y - x + 1];
return dep[dfn[mn[y][len]]] < dep[dfn[mn[x + (1 << len) - 1][len]]] ?
dfn[mn[y][len]] : dfn[mn[x + (1 << len) - 1][len]];
}
void dfs(int pos,int fa) {
dep[pos] = dep[fa] + 1;
dfn[rec[pos] = ++dcnt] = pos;
for (int i = fir[pos] ; i ; i = con[i].la) {
if (con[i].b == fa) continue;
dis[con[i].b] = dis[pos] + con[i].v;
dfs(con[i].b,pos);
dfn[++dcnt] = pos;
}
}
typedef pair<int,int> pii;
pii t[N << 2];
return dis[x] + dis[y] - 2 * dis[lca(x,y)];
}
void merge(pii& x,pii ls,pii rs) {
static int rec[4];
rec[0] = ls.first;
rec[1] = ls.second;
rec[2] = rs.first;
rec[3] = rs.second;
x = pii(-1,-1);
int cur = -1, tmp;
for (int i = 0 ; i < 4 ; ++ i)
for (int j = i+1 ; j < 4 ; ++ j) {
if (rec[i] == -1 || rec[j] == -1) continue;
if (tmp > cur) x = pii(rec[i],rec[j]), cur = tmp;
}
}
void build(int x=1,int lp=1,int rp=n) {
if (lp == rp)
return (void) (t[x] = pii(lp,-1));
int mid = (lp + rp) >> 1;
build(x<<1,lp,mid);
build(x<<1|1,mid+1,rp);
merge(t[x],t[x<<1],t[x<<1|1]);
}
pii query(int l,int r,int x=1,int lp=1,int rp=n) {
if (l > rp || lp > r) return pii(-1,-1);
if (lp >= l && rp <= r)
return t[x];
int mid = (lp + rp) >> 1;
pii ret;
merge(ret,query(l,r,x<<1,lp,mid),query(l,r,x<<1|1,mid+1,rp));
return ret;
}
int main() {
int x,y,z,a,b,c,d;
for (int i = 1 ; i < n ; ++ i) {
}
dfs(1,0);
for (int i = 1 ; i <= dcnt ; ++ i) {
mn[i][0] = i;
for (int j = 1 ; (1 << j) <= i ; ++ j)
mn[i][j] = dep[dfn[mn[i][j-1]]] < dep[dfn[mn[i - (1 << j >> 1)][j-1]]] ?
mn[i][j-1] : mn[i - (1 << j >> 1)][j-1];
}
for (int i = 2 ; i <= dcnt ; i <<= 1)
++ ln[i];
for (int i = 2 ; i <= dcnt ; ++ i)
ln[i] += ln[i-1];
build();
}