大红大紫了属于是
查看原帖
大红大紫了属于是
386852
Selvare楼主2021/11/18 17:51

WAA

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 5,INF = 1e9;
int n, m;
int fa[N], dep[N], hson[N], sz[N], link[N];
int dfn[N], rnk[N], top[N], dfncnt;
int Left[N], Right[N], section[N], seccnt;

struct edge
{
	int cnt;
	int head[N<<1], nxt[N<<1], to[N<<1], val[N<<1];
	void addE(int x, int y, int z = 0)
	{
		nxt[++cnt] = head[x];
		to[cnt] = y;
		val[cnt] = z;
		head[x] = cnt;
	}
}ed;

struct BinaryIndexedTree
{
	int sum[N];
	int lowbit(int k) { return k & (-k);}
	void update(int x, int k) 
	{ 
		for(int i = x; i <= n; i += lowbit(i)) 
			sum[i] += k;
	}
	int query(int x)
	{ 
		int i = x, res = 0;
		for(int i = x; i >= 1; i -= lowbit(i)) 
			res += sum[i]; 
		return res;
	}
	void build(int x)
	{
		for(int i = 1; i <= n; ++i)
			update(i, link[rnk[i]]);
	}
	int getsum(int l, int r)
	{
		return query(r) - query(l-1);
	}
}BIT;

struct SegmentTree
{
	#define ls (now<<1)
	#define rs (now<<1|1)
	#define mid (s+t>>1)
	int maxx[N<<2], tag[N<<2];
	void up(int now) { maxx[now] = max(maxx[ls], maxx[rs]);}
	void down(int now)
	{
		if(!tag[now]) return;
		tag[ls] = max(tag[ls], tag[now]);
		tag[rs] = max(tag[rs], tag[now]);
		maxx[ls] = max(tag[now], maxx[ls]);
		maxx[rs] = max(tag[now], maxx[rs]);
		tag[now] = 0;
	}
	int getmax(int s, int t, int now, int x)
	{
		if(s == t) return maxx[now];
		down(now);
		return x <= mid ? getmax(s, mid, ls, x) : getmax(mid+1, t, rs, x);
	}
	void update(int s, int t, int l, int r, int now, int val)
	{
		if(l <= s && t <= r)
		{
			maxx[now] = max(maxx[now], val);
			tag[now] = max(tag[now], val);
			return;
		}
		down(now);
		if(l <= mid) update(s, mid, l, r, ls, val);
		if(r > mid) update(mid+1, t, l, r, rs, val);
		up(now);
	}
}ST;

void dfs(int now, int f = 0, int val = 0)
{
	sz[now] = 1;
	fa[now] = f;
	link[now] = val;
	dep[now] = dep[fa[now]] + 1;
	for(int i = ed.head[now]; i; i = ed.nxt[i])
	{
		int v = ed.to[i];
		if(v == f) continue;
		dfs(v, now, ed.val[i]);
		sz[now] += sz[v];
		if(!hson[now] || sz[hson[now]] < sz[v]) hson[now] = v;
	}
}

void deco(int now, int tp)
{
	dfn[now] = ++dfncnt;
	rnk[dfncnt] = now;
	top[now] = tp;
	if(!hson[now]) return;
	deco(hson[now], tp);
	for(int i = ed.head[now]; i; i = ed.nxt[i])
	{
		int v = ed.to[i];
		if(v == fa[now] || hson[now] == v) continue;
		deco(v, v);
	}
}

int path_s, path_t, path_l;
int get_len(int u, int v)
{
	int len = 0;
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		len += BIT.getsum(dfn[top[u]], dfn[u]);
		u = fa[top[u]];
	}
	if(dfn[u] < dfn[v]) swap(u, v);
	if(u != v)len += BIT.getsum(dfn[v]+1, dfn[u]);
	if(len > path_l)
	{
		path_l = len;
		path_s = u;
		path_t = v;
	}
	return len;
}

bool cmp(int a, int b) { return Left[a] < Left[b];}
void update(int u, int v, int len)
{
	seccnt = 0;
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		Left[++seccnt] = dfn[top[u]], Right[seccnt] = dfn[u], section[seccnt] = seccnt;
		u = fa[top[u]];
	}
	if(dfn[u] < dfn[v]) swap(u, v);
	Left[++seccnt] = dfn[v]+1, Right[seccnt] = dfn[u], section[seccnt] = seccnt;
	sort(section+1, section+1+seccnt, cmp);
	if(Left[section[1]] > 1) ST.update(1, n, 1, Left[section[1]]-1, 1, len);
	if(Right[section[seccnt]] < n) ST.update(1, n, Right[section[seccnt]]+1, n, 1, len);
	for(int i = 1; i < seccnt; ++i) ST.update(1, n, Right[section[i]]+1, Left[section[i+1]]-1, 1, len);
}

int ans = INF;
void solve(int u, int v, int len)
{
	if(u == v)
	{
		cout <<"0\n";
		return;
	}
	while(top[u] != top[v])
	{
		if(dep[top[u]] < dep[top[v]]) swap(u, v);
		ans = min(ans, max(len-link[u], ST.getmax(1, n, dfn[u], 1)));
		u = fa[u];
	}
	if(dfn[u] < dfn[v]) swap(u, v);
	while(u != v)
	{
		ans = min(ans, max(len-link[u], ST.getmax(1, n, dfn[u], 1)));
		u = fa[u];
	}
	cout << ans;
}

int main()
{
	mt19937 myrand(time(0));
	cin >> n >> m;
	for(int i = 1, x, y, z; i < n; ++i)
	{
		cin >> x >> y >> z;
		ed.addE(x, y, z);
		ed.addE(y, x, z);
	}
	int root = myrand()%n+1;
	dfs(root);
	deco(root, root);
	BIT.build(n);
	for(int i = 1, x, y; i <= m; ++i)
	{
		cin >> x >> y;
		int len = get_len(x, y);
	//	cout << len <<endl;
		update(x, y, len);
	}
	solve(path_s, path_t, path_l);
}

做法和第一篇题解思路基本完全一致,然后rand了个根之后每次输出结果居然都能不一样。。。(样例有时候输出15有时候输出11

2021/11/18 17:51
加载中...