首页 > 系统相关 >CodeForces 342E Xenia and Tree

CodeForces 342E Xenia and Tree

时间:2024-01-20 23:24:26浏览次数:29  
标签:typedef int Tree CodeForces long Xenia dfn maxn define

洛谷传送门

CF 传送门

比较谔谔,为什么题解区都在群魔乱舞。不是有个很简单的点分树做法吗。

考虑建出点分树,由点分树的性质可得任意两点在点分树上的 LCA 一定在它们的路径上。然后每次暴力跳父亲,每个分治中心维护一个 \(f_i\) 表示距离 \(i\) 最近的红色点的距离即可。

若使用 dfn 序 st 表求 lca,时间复杂度为 \(O((n + m) \log n)\)。

有操作分块的做法,大概懂了。就是每 \(O(\sqrt{m})\) 次操作分块,遍历到块左端点时先预处理出所有点到红色点的最短距离,然后块内只会加入 \(O(\sqrt{m})\) 个红色点,这部分可以暴力枚举。总时间复杂度 \(O(n \sqrt{m})\)。

code
// Problem: E. Xenia and Tree
// Contest: Codeforces - Codeforces Round 199 (Div. 2)
// URL: https://codeforces.com/problemset/problem/342/E
// Memory Limit: 256 MB
// Time Limit: 5000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 100100;
const int logn = 20;

int n, m, fa[maxn], sz[maxn], f[maxn], rt;
int dep[maxn], dfn[maxn], tim, st[logn][maxn];
vector<int> G[maxn];
bool vis[maxn];

inline int get(int i, int j) {
	return dfn[i] < dfn[j] ? i : j;
}

inline int qlca(int x, int y) {
	if (x == y) {
		return x;
	}
	x = dfn[x];
	y = dfn[y];
	if (x > y) {
		swap(x, y);
	}
	++x;
	int k = __lg(y - x + 1);
	return get(st[k][x], st[k][y - (1 << k) + 1]);
}

inline int qdis(int x, int y) {
	return dep[x] + dep[y] - dep[qlca(x, y)] * 2;
}

void dfs2(int u, int fa, int t) {
	f[u] = 0;
	sz[u] = 1;
	for (int v : G[u]) {
		if (v == fa || vis[v]) {
			continue;
		}
		dfs2(v, u, t);
		sz[u] += sz[v];
		f[u] = max(f[u], sz[v]);
	}
	f[u] = max(f[u], t - sz[u]);
	if (!rt || f[u] < f[rt]) {
		rt = u;
	}
}

void dfs(int u) {
	vis[u] = 1;
	for (int v : G[u]) {
		if (vis[v]) {
			continue;
		}
		rt = 0;
		dfs2(v, -1, sz[v]);
		dfs2(rt, -1, sz[v]);
		fa[rt] = u;
		dfs(rt);
	}
}

void dfs3(int u, int fa) {
	dfn[u] = ++tim;
	st[0][tim] = fa;
	dep[u] = dep[fa] + 1;
	for (int v : G[u]) {
		if (v == fa) {
			continue;
		}
		dfs3(v, u);
	}
}

void solve() {
	scanf("%d%d", &n, &m);
	for (int i = 1, u, v; i < n; ++i) {
		scanf("%d%d", &u, &v);
		G[u].pb(v);
		G[v].pb(u);
	}
	rt = 0;
	dfs2(1, -1, n);
	dfs2(rt, -1, n);
	dfs(rt);
	dfs3(1, 0);
	mems(f, 0x3f);
	for (int j = 1; (1 << j) <= n; ++j) {
		for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
			st[j][i] = get(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
	for (int i = 1; i; i = fa[i]) {
		f[i] = min(f[i], qdis(1, i));
	}
	while (m--) {
		int op, x;
		scanf("%d%d", &op, &x);
		if (op == 1) {
			for (int i = x; i; i = fa[i]) {
				f[i] = min(f[i], qdis(x, i));
			}
		} else {
			int ans = 1e9;
			for (int i = x; i; i = fa[i]) {
				ans = min(ans, f[i] + qdis(x, i));
			}
			printf("%d\n", ans);
		}
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,int,Tree,CodeForces,long,Xenia,dfn,maxn,define
From: https://www.cnblogs.com/zltzlt-blog/p/17977319

相关文章

  • 比赛必备——codeforces better 和 atcoder better 的安装教程
    大家有没有像我一样英语不太好然后又想要打cf和atc的呢?(可能全世界就我英语不好)这里有两个强力的工具可以帮助我们解决这一问题——codeforcesbetter和atcoderbetter。由于我只用的是edge,所以下面默认为edge浏览器篡改猴首先我们需要安装篡改猴,link。codeforcesbe......
  • compareTo、Comparator、TreeSet排序那些事
    前言:对于后端开发而言,学会对数据的自定义排序还是十分有必要的。需要用到排序的场景也是很多的,什么排行版展示、利用时间+别的条件排序、还有预接单的数据就是要展示在已接单的数据前面这种需求、等等。总之很重要的!一:对集合排序对以下的数据做展示顺序排序:未接单>预接单>已接单。(......
  • hey_left 10 Codeforces Round 871 (Div. 4) 再续
    题目链接H.没思路,查看题解选择数组的非连续的子序列,就是每个数选或不选的问题求个数,易dp求子序列的数二进制相与结果有k个1的个数把所有结果记录,再去筛选满足条件的结果f[i][j]表示到第i个数,相与结果为j的子序列个数正向思维:多个数相与得到结果dp思维:枚举结果,考虑数如何......
  • hey_left 9 Codeforces Round 871 (Div. 4) 续
    题目链接E.连通块的搜索debug:用不上回溯,把连通块的贡献全部加起来#include<bits/stdc++.h>usingnamespacestd;intn,m;intg[1010][1010];boolvis[1010][1010];intma,tmp;intdx[5]={-1,1,0,0};intdy[5]={0,0,1,-1};voiddfs(intx,inty){tmp+=g[x][y];......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    基本情况A犯病卡半小时。主要就是太着急,题目没有彻底分析清楚就开始想一些错误做法。C最优想法出来的慢。E比较好想。C.ClosestCitiesProblem-C-Codeforces就,显然是能走最近城市就走,不行就不走。一开始弄了一个自作聪明的预处理,但实际上每次查询还是\(\operatorn......
  • Codeforces Round 920 (Div. 3)
    题目链接点这里这场div3F题的算法很基础,但是我此前居然完全没接触过。(芙莉莲震惊.jpg)不过这下能够算法沙漠面积--了。CF1921ASquarevoidsolve(){intx1=1e9,y1=1e9,x2=-1e9,y2=-1e9,x,y;for(inti=1;i<=4;++i){cin>>x......
  • [操作系统] 打印进程树 pstree
    打印进程树简介这是jyy老师的操作系统课程的M1实验,为了弥补一些欠缺的操作系统相关的知识。在这里实现的的pstree并不是严格的按照实验要求而设计的(一个原因是按要求实现的代码不可以公开),这里会看到一些不一样的简单实现,比如直接运行,没有命令行可选参数,输出格式会有所不同......
  • 解决 Ant TreeSelect(树选择)组件可以使用键盘选中 disabled(已禁用)项的问题
    最近在使用AntDesignVue(V3.2.20)的TreeSelect组件时发现一个问题:tree-data中部分数据的disabled属性设置为了true,选项是“禁用”状态,无法通过鼠标点击选中,但是可以通过键盘↑↓键切换选项,按下Enter键选中。一开始还以为是bug,后来通过查阅文档和测试发现,该组件还......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    A.TrickyTemplate思维有点难转过来,而且当时在C也能匹配c这卡了很久#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ intn; cin>>n; stringa,b,c; cin>>a>>b>>c; intcnt=0; intf=0; for(inti=0;i<n;i++){ if(a[i]!=c[i]&&a......
  • Codeforces Round 919 (Div. 2)
    目录写在前面ABCDE写在最后写在前面比赛地址:https://codeforces.com/contest/1920考试周突然发癫想打cf但是觉得肯定打不完所以拿小号打的。手速慢了没上大分呃呃A求出上下界来,再求被限制的数有多少个在区间内即可。///*By:Luckyblock*/#include<bits/stdc++.h>#de......