首页 > 其他分享 >[ABC328F] Good Set Query 题解

[ABC328F] Good Set Query 题解

时间:2023-12-19 12:13:19浏览次数:22  
标签:Set fx int 题解 fa MAXN Query Find define

复习了一下边带权并查集板子。

设 \(d_{x}\) 表示当前点到它所在连通块根节点的距离。

合并点 \(x\) 和点 \(y\) 所在两个连通块时需要更新 \(d\)。因为将 \(x\) 点所在连通块的根节点的父亲节点设为了 \(y\) 点所在连通块的根节点,所以有 \(x \to y \to Find(y)=x \to Find(x) \to Find(y)\),更新 \(d_{Find(x)}=d_{y}+z-d_{x}\),其中 \(z\) 是 \(x\) 点到 \(y\) 点的距离。

路径压缩的时候也需要更新 \(d\),直接将 \(d_{x}\) 加上 \(d_{fa_{x}}\) 即可。

\(i\) 可以被加入集合 \(S\),当且仅当当前的 \(x\) 和 \(y\) 不在一个连通块或者 \(x\) 到 \(y\) 的距离为 \(z\)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f
#define inf_db 127
#define ls id << 1
#define rs id << 1 | 1
#define re register
#define endl '\n'
typedef pair <int,int> pii;
const int MAXN = 2e5 + 10;
int n,q,x,y,z,d[MAXN],fa[MAXN],ans[MAXN],cnt;
inline int Find(int x)
{
	if(x == fa[x]) return x;
	int f = fa[x];
	fa[x] = Find(fa[x]),d[x] += d[f];
	return fa[x];
}
signed main()
{
	cin >> n >> q;
	for(int i = 1;i <= n;i++) fa[i] = i;
	for(int i = 1;i <= q;i++)
	{
		cin >> x >> y >> z;
		int fx = Find(x),fy = Find(y);
		if(fx != fy)
			fa[fx] = fy,d[fx] = d[y] - d[x] + z,ans[++cnt] = i;
		else if(d[x] - d[y] == z) 
			fa[fx] = fy,d[fx] = d[y] - d[x] + z,ans[++cnt] = i;
	}
	for(int i = 1;i <= cnt;i++) cout << ans[i] << " ";
	return 0;
}

标签:Set,fx,int,题解,fa,MAXN,Query,Find,define
From: https://www.cnblogs.com/Creeperl/p/17913408.html

相关文章

  • P6370 [COCI2006-2007#6] KAMEN 题解
    原题链接:P6370思路题意不多赘述。首先这道题的\(60\)分暴力很好打,直接按题目中的操作做即可,时间复杂度\(O(nr)\)。考虑优化暴力。我们会发现很多次石头的起始点为同一列的情况,其实每一次下落的轨迹是差不多的。具体来讲应该是第一次下落的轨迹一定包含了后面每一次的轨迹。......
  • P4786 [BalkanOI2018] Election 题解
    题意给定一个长度为\(n\)的字符串\(s\),有\(m\)个询问,每次询问最少需要删掉多少个字符才能使\(l\)到\(r\)组成的字符串当中的每一个前缀和后缀都满足C的数量不小于T的数量。思路因为要满足C的数量不小于T的数量,我们不妨设字符C的位置的值为\(1\),字符S的位......
  • P8386 [PA2021] Od deski do deski 题解
    显然是一道计数dp。dp状态应该是最难的一部分了,个人认为这种状态设计得比较巧妙。如果像我刚开始一样设\(dp_{i,j}\)表示序列中一共有\(i\)个数,序列最后一个数为\(j\)的合法方案数的话,那么方程就会变得很不好转移,因为我们不知道当前的\(j\)和之前的某些数能不能匹配上,......
  • C0328 【1005 C组】模拟测试 斜率 题解
    原题链接:斜率。题意在一个平面直角坐标系中,给定\(n\)个点的横纵坐标,求出哪两个点所构成的连线的斜率最接近\(\frac{P}{Q}\)。数据范围:\(n\le1000000\)。思路显然这是一道数学题,不能直接暴力去找答案。首先我们可以弱化一下题目,求出斜率最接近\(y=0\)即\(x\)轴的两......
  • Omkar and Akmar 题解
    题意:有一个\(n\)个点的环,以及两个人。每个人可以向环中任意一个位置放置一个\(A\)或者\(B\),但是相邻的位置不能相同,不能行动者输。问最终的局面有多少种。一个结论是:后手必胜。证明:最终肯定不可能出现两个连续的空格,否则一定可以在其中一个上填\(A\)或\(B\)。所以最多只......
  • Square-free division (easy version) 题解
    题意:给定一个长度为\(n\)的序列,求最少能将这个序列分成多少段使得任意一段中不存在两个数的积为完全平方数。一个小Trick:如果两个数乘起来为平方数,可以先将每个数的平方因子除掉,然后这两个数必然相等。于是这道题被转化为了一个区间不能有相等的值,这就很典了。设\(pos_{a_{i......
  • Animals and Puzzle 题解
    原题链接:CF713D题意:给定一个\(n\timesm\)的地图\(a\),\(a_{i}\)为\(0\)或\(1\)。有\(t\)次询问,每次询问给定一个矩形,求出这个矩形中最大的由\(1\)构成的正方形的边长是多少。首先考虑预处理出\(d_{i,j}\)表示以\((i,j)\)为左上角的最大正方形边长是多少。对于每......
  • C0392 B 【1109 B组】预处理器 题解
    题意:求有多少个长度为\(n\)的数组\(a\)满足以下条件。条件一:\(l_{i}\lea_{i}\ler_{i}\)。条件二:\(a_{i}\)模\(2\)等于\(p_{i}\)。条件三:\(s\le\suma_{i}\let\)。求答案模\(mod\)的值,\(mod\)不一定是一个质数。数据范围:\(n\le13\)。又积累到一......
  • A Simple Task 题解
    这道题比较简单,简述一下思路。考虑状压\(DP\)。设\(dp_{i,j}\)表示走到第\(i\)个点,之前走过的点的状态为\(j\)的环的数量。这里有一个细节,就是我们都钦定每个走过的第一点是整个状态中编号最小的点,这样不会重复计算。考虑如何进行转移。如果当前点的编号比走过的最小编......
  • CF1900D Small GCD 题解
    原题链接:CF1900D,题意不多赘述。首先可以将\(a\)数组排序,并且枚举中间的那个数\(a_i\)。那么答案就是\(\sum_{j=1}^{i-1}\gcd(a_j,a_i)\times(n-i)\)。重点在于求前面的\(\gcd\)。可以用欧拉反演,但是也可以不用,因为我不会。假设我们当前已经枚举到了\(a_i\),设\(f_k\)表......