首页 > 其他分享 >Codeforces Round 767 (Div. 1) E. Groceries in Meteor Town (Kruskal重构树 + 线段树)

Codeforces Round 767 (Div. 1) E. Groceries in Meteor Town (Kruskal重构树 + 线段树)

时间:2023-05-16 22:47:56浏览次数:52  
标签:Town std rs int Kruskal tr 767 ls leader

传送门

  出现最大路径权值就应该联想到克鲁斯卡尔重构树,我们对于克鲁斯卡尔重构树求一遍dfs序,维护所有白色点的最大最小dfn(包括出发点),求出最大最小dfn的最近公共祖先既是答案。注意需要特判一下除了本身以外没有白色点情况。

#include <bits/stdc++.h>

int n, m;
const int N = 6e5 + 10; 
typedef long long ll;
const int INF = 0x3f3f3f3f;
typedef std::array<int, 3> A;

std::vector<A> edge;

int a[N], val[N];

int h[N], ne[N], e[N], w[N], idx;

int fa[N][20], timedelta, id[N], rid[N], dep[N];

inline void add(int a, int b) {
	ne[idx] = h[a], e[idx] = b, h[a] = idx ++;
}

int tot;

struct DSU {
    std::vector<int> f, sz;
    DSU(int n) : f(n + 1), sz(n + 1, 1) { std::iota(f.begin(), f.end(), 0); }
    int leader(int x) {
        while (x != f[x]) x = f[x] = f[f[x]];
        return x;
    }
    bool same(int x, int y) { return leader(x) == leader(y); }
    bool merge(int x, int y) {
        x = leader(x);
        y = leader(y);
        if (x == y) return false;
        sz[x] += sz[y];
        f[y] = x;
        return true;
    }
    int size(int x) { return sz[leader(x)]; }
};

inline void Kruskal() {
	memset(h, -1, sizeof h);
	std::sort(edge.begin(), edge.end());
	DSU dsu(N);
	tot = n;
	for (int i = 0; i < n - 1; i ++) {
		auto &[v, a, b] = edge[i];
		a = dsu.leader(a), b = dsu.leader(b);
		val[++ tot] = v;
		dsu.f[tot] = dsu.f[a] = dsu.f[b] = tot;
		add(tot, a), add(tot, b);
	}
}

struct node {
	int l, r;
	int usedmx, usedmn;
	int mx, mn;
	int tag;
}tr[N << 2];

#define ls u << 1
#define rs u << 1 | 1

inline void pushup(int u) {
	tr[u].usedmx = std::max(tr[ls].usedmx, tr[rs].usedmx);
	tr[u].usedmn = std::min(tr[ls].usedmn, tr[rs].usedmn);
	tr[u].mx = std::max(tr[ls].mx, tr[rs].mx);
	tr[u].mn = std::min(tr[ls].mn, tr[rs].mn);
}

inline void build(int u, int l, int r) {
	tr[u].usedmx = 0, tr[u].usedmn = INF;
	if (l == r) {
		tr[u].mx = tr[u].mn = id[l];
		return ;
	}
	
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	
	pushup(u);
}

inline void pushdown(int u) {
	if (tr[u].tag) {
		if (tr[u].tag == 1) {
			tr[ls].tag = tr[rs].tag = 1;
			tr[ls].usedmx = tr[ls].mx;
			tr[ls].usedmn = tr[ls].mn;
			tr[rs].usedmx = tr[rs].mx;
			tr[rs].usedmn = tr[rs].mn;
		} else {
			tr[ls].tag = tr[rs].tag = -1;
			tr[ls].usedmx = 0;
			tr[ls].usedmn = INF;
			tr[rs].usedmx = 0;
			tr[rs].usedmn = INF;
		}
		tr[u].tag = 0;
	}
}

inline void modify(int u, int L, int R, int l, int r, int x) {
	if (L >= l && R <= r) {
		if (x == 1) {
			tr[u].usedmx = tr[u].mx;
			tr[u].usedmn = tr[u].mn;
			tr[u].tag = 1;
		} else {
			tr[u].usedmx = 0;
			tr[u].usedmn = INF;
			tr[u].tag = -1;
		}
		return ;
	}
	
	pushdown(u);
	
	int mid = L + R >> 1;
	if (l <= mid)	modify(ls, L, mid, l, r, x);
	if (r > mid)	modify(rs, mid + 1, R, l, r, x);
	
	pushup(u);
}

inline void dfs(int u, int father, int depth) {
	fa[u][0] = father; 	id[u] = ++ timedelta, rid[timedelta] = u;
	dep[u] = depth;
	for (int i = 1; i <= 19; i ++) fa[u][i] = fa[fa[u][i - 1]][i - 1];

	for (int i = h[u]; ~i; i = ne[i]) {
		int j = e[i];
		dfs(j, u, depth + 1);
	}
}

inline int LCA(int a, int b) {
	if (dep[a] < dep[b]) std::swap(a, b);
	for (int i = 19; ~i; i --) 
		if (dep[fa[a][i]] >= dep[b]) a = fa[a][i];
	
	if (a == b) return a;
	
	for (int i = 19; ~i; i --) 
		if (fa[a][i] != fa[b][i]) {
			a = fa[a][i];
			b = fa[b][i];
		}
	
	return fa[a][0];
}

#undef ls u << 1
#undef rs u << 1 | 1
inline void solve() {
	std::cin >> n >> m;
	
	for (int i = 0; i < n - 1; i ++) {
		int a, b, c;
		std::cin >> a >> b >> c;
		edge.push_back({c, a, b});
	}

	Kruskal();
	
	dfs(tot, 0, 1);
	build(1, 1, n);
	
	while (m --) {
		int op;
		std::cin >> op;
		if (op <= 2) {
			int l, r;
			std::cin >> l >> r;
			if (op == 1) modify(1, 1, n, l, r, 1);
			else modify(1, 1, n, l, r, -1);
		} else {
			int x;
			std::cin >> x;
			int a = tr[1].usedmx, b = tr[1].usedmn;
			a = std::max(id[x], a), b = std::min(id[x], b);
			a = rid[a], b = rid[b];
			if (a == b) std::cout << -1 << '\n';
			else std::cout << val[LCA(a, b)] << '\n';
		}
	}
}

int main(void) {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	
	int _ = 1;
	
	while (_ --) solve();
	
	return 0;
}

标签:Town,std,rs,int,Kruskal,tr,767,ls,leader
From: https://www.cnblogs.com/qdhys/p/17380745.html

相关文章

  • 【哈希表】LeetCode 767. 重构字符串
    题目链接767.重构字符串思路先用哈希表统计出出现次数最多的字符,如果这个次数大于一半,说明这个字符总会挨在一起,直接返回""。如果不超过一半,则先把字符填在偶数位置(先填出现次数最多的字符),偶数位置填满了再填奇数位置。代码classSolution{publicStringreorganize......
  • AGC002D Stamp Rally 多种做法 kruskal重构树/可持久化并查集/整体二分
    D-StampRally(atcoder.jp)这题做法很多,我写的是可持久化并查集做法,但是裸的可持久化并查集是$O(nlog^3n)$,能过但是很慢!看洛谷的题解有一位大佬写了一个很妙的并查集的写法,按秩合并,每一步合并时用vector记录一下这个被合并到的节点的size和当前的时间,这样做可以找到每一个时......
  • mysql Error:index column size too large. the maximum column size is 767 bytes
    问题现象mysql在执行脚本create创建表时,提示以下错误:indexcolumnsizetoolarge.themaximumcolumnsizeis767bytes异常原因INNODB引擎,UTF-8,主键字符串默认最大767,需要修改解决方案对数据库进行设置setglobalinnodb_large_prefix=ON参考博客......
  • [uoj234]Towns
    记直径为\((x,y)\),则有以下做法:利用直径的经典做法,可以\(3n\)次询问得到\(x,y\)和其余点到\(x,y\)的距离设直径上距离\(i\)最近的点为\(k\),已知\(x,y,i\)两两距离,即可......
  • 阿里云数据库RDS迁移导入数据时报错:Specified key was too long; max key length is 76
    近期由于新申请了新的阿里云数据库RDS,需要把之前的数据迁移过去,结果通过各种方式去导入数据,都一直报错.报错信息:Indexcolumnsizetoolarge.Themaximumcolumnsize......
  • 6.Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x000000079
    这个问题引起的原因是:服务器上物理内存太小,大部分都是应为程序太多,内存吃紧,而给jvm分配的内存太大(java程序启动需要的内存,linux不能给),最好调整java程序jvm内存吧(测试环......
  • mysql: Specified key was too long; max key length is 767 bytes
    问题记录:原因如果该字段参与了索引,在对该字段进行拓展长度时会提示超过索引最大值我使用的解决方案,在使用联合索引时使用改字段的前一部分作为联合索引\然后再......
  • 图论:Kruskal重构树
    瓶颈路两点间所有路径中\(\max(w)\)最小或\(\min(w)\)最大的路径称为最小/最大瓶颈路。Kruskal重构树考虑kruskal算法的贪心过程,注意到一张图的一个最小生成树是......
  • 从零开始学习Kruskal最小生成树
    -1919810.前言如果你想要学好Kruskal最小生成树的话,那么你就得先学好Kruskal最小生成树,你一看这个Kruskal最小生成树,你想掌握它还真不容易,基础知识里头你就得掌握Kruskal......
  • 最小生成树(Kruskal & Prim)
    最小生成树定义对于一个带权连通无向图G=(V,E),生成树不同,每棵树的权(树中所有边上的权值和)也不同,设R为G的所有生成树的集合,若T为R中权值和最小的生成树,则T称为G的最小生成......