loj #137 and #6021

最小瓶颈路 加强版
重构树
最小生成树在合并 (x, y) 时,新建节点 z,link(x, z), link(y, z), 新建节点的权值为 w_{x,y}, 这样的

话任意两点的 answer 为新树上两点 lca 的权值,由于询问次数非常多,显然不可以 logn 求 lca。这里利用

RMQ 求 lca,预处理后时间复杂度 O(1)

#include <bits/stdc++.h>

const int N = 7e4 + 10, M = 1e5 + 10, Mod = 1e9 + 7;

int n, m;
struct Node {
	int u, v, w;
	bool operator < (const Node a) const {return w < a.w;}
} E[M];
int A, B, C, P;

inline int Rand() {A = (A * B + C) % P; return A;}

int fa[N << 1];
int Get(int x) {return x == fa[x] ? x : fa[x] = Get(fa[x]);}

std:: vector <int> Vec[N << 1];
int tot_point;
int Val[N << 1];

void Rebuild() {
	tot_point = n;
	for(int i = 1; i <= (n << 1); i ++) fa[i] = i;
	for(int i = 1; i <= m && tot_point != n + n - 1; i ++) {
		int fau = Get(E[i].u), fav = Get(E[i].v);
		if(fau != fav) {
			tot_point ++;
			fa[fau] = fa[fav] = tot_point;
			Vec[tot_point].push_back(fau);
			Vec[tot_point].push_back(fav);
			Val[tot_point] = E[i].w;
		}
	}
}

int deep[N << 1], In[N << 1], Id[N << 2];
int Tr;

void Dfs(int u, int dep) {
	deep[u] = dep, In[u] = ++ Tr; Id[Tr] = u; 
	int S = Vec[u].size();
	for(int i = 0; i < S; i ++) Dfs(Vec[u][i], dep + 1), Id[++ Tr] = u;
}

int f[N << 2][30], Pow[30], Log[N << 2];

#define T Tr
void Make_st() {
	for(int i = 0; (Pow[i] = (1 << i)) <= T; i ++);
	Log[1] = 0;
	for(int i = 2; i <= T; i ++) Log[i] = Log[i >> 1] + 1;
	for(int i = 1; i <= T; i ++) f[i][0] = Id[i];
	for(int i = 1; Pow[i] <= T; i ++)
		for(int j = 1, ti = T - Pow[i] + 1; j <= ti; j ++)
			f[j][i] = (deep[f[j][i - 1]] < deep[f[j + Pow[i - 1]][i - 1]] ? f[j][i - 

1] : f[j + Pow[i - 1]][i - 1]);
}

int main() {
	std:: cin >> n >> m;
	for(int i = 1; i <= m; i ++) {
		int u, v, w; std:: cin >> u >> v >> w;
		E[i] = (Node) {u, v, w};
	}
	std:: sort(E + 1, E + m + 1);
	Rebuild();
	Dfs(tot_point, 1);
	Make_st();
	int Q; std:: cin >> Q;
	std:: cin >> A >> B >> C >> P;
	int Ans = 0;
	for(; Q; Q --) {
		int _1 = Rand() % n + 1, _2 = Rand() % n + 1;
		int u = In[_1], v = In[_2];
		if(u == v) continue;
		if(u > v) std:: swap(u, v);
		int t;
		int ID = f[u][t = Log[v - u + 1]];
		if(deep[ID] > deep[f[v - Pow[t] + 1][t]]) ID = f[v - Pow[t] + 1][t];
		if((Ans += Val[ID]) >= Mod) Ans -= Mod;
	}
	std:: cout << Ans;
	return 0;
}
posted @ 2018-09-19 09:05  xayata  阅读(142)  评论(0编辑  收藏  举报