首页 > 其他分享 >带权并查集

带权并查集

时间:2024-12-28 14:51:54浏览次数:5  
标签:ty int 查集 更新 带权 find define

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define x first
#define y second
#define int long long 
const int N=1e6+10,mod=998244353;

int f[N],w[N];//w[i]表示i这个点比根节点的值大多少 

int find(int x){
	if(f[x]==x) return x;
	int p=f[x];
	find(p);
	/*
	更新前:f[x]=p,w[x]=a[x]-a[p]
	更新前:f[p]=q, w[p]=a[p]-a[q]
	更新后:f[x]=q, w[x]=a[x]-a[q]
	w[x](更新前)+w[p]=a[x]-a[p]+a[p]-a[q]=a[x]-a[q]=w[x](更新后)
	*/
	w[x]+=w[p];
	return f[x]=f[p];
}

void slove(){
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		f[i]=i;
		w[i]=0;
	}
	int t=0;
	while(q--){
		int ty,l,r;
		cin>>ty>>l>>r;
		l=(l+t)%n+1;
		r=(r+t)%n+1;
		if(ty==2){
			if(find(l)!=find(r))continue;
			cout<<w[l]-w[r]<<endl;
			t=abs(w[l]-w[r]);
		}else {
			if(find(l)==find(r)) continue;
			//只要统计根节点之间的关系即可,后续的更新会在find中完成 
			/*
			w[f[l]]=a[f[l]]-a[f[r]];
			a[l]-a[r]=x;
			a[l]-w[l]-(a[r]-w[r])=a[f[l]]-a[f[r]]
			*/
			w[f[l]]=x-w[l]+w[r];
			f[f[l]]=f[r];//l并为r的儿子节点
		}
	} 
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	int T=1;
	while(T--) slove();
}

标签:ty,int,查集,更新,带权,find,define
From: https://www.cnblogs.com/mendax-Z/p/18637497

相关文章

  • 代码随想录算法训练营第五十五天|并查集理论基础、寻找存在的路径
    前言打卡代码随想录算法训练营第49期第五十五天(~ ̄▽ ̄)~首先十分推荐学算法的同学可以先了解一下代码随想录,可以在B站卡哥B站账号、代码随想录官方网站代码随想录了解,卡哥清晰易懂的算法教学让我直接果断关注,也十分有缘和第49期的训练营大家庭一起进步。学习今天的课程前,先看并......
  • 开拓计划4 - 二叉树与并查集
    开拓计划4-二叉树与并查集二叉树二叉树的概念Q:什么是树?A:一种有\(n\)个节点最多有\(n-1\)条边的图。Q:什么是二叉树?A:每个节点都最多只有两个子节点的树。二叉树和递归Q:二叉树和递归有什么关系?A:在执行递归的时候总是会自己调用自己,每一次调用都会产生新的一层,新......
  • NKOJ 1209 并查集【NOI2001 Day1 T3】食物链
    NKOJ1209并查集【NOI2001Day1T3】食物链思路:带权/种类并查集方法一实现方法用带权并查集带的权值是边权,不是点权,用来表示两点间的关系,但为了方便记录还是用点权,每个点记录到根节点的权值。在getf函数中注意更新是到根节点之间的权值,用\(val_x=(val_x+val_{fa_x})\bm......
  • NKOJ 2107 【并查集】可爱的猴子
    NKOJ2107【并查集】可爱的猴子思路:普通并查集+图的遍历更新答案实现方法首先使用时光倒流思想解决删边的问题。注意提前把没有删过的边提前建上。接着用一个图记录猴子之间的拉手关系,每次要更新答案时都遍历与当前节点连着的节点将其答案更新,只有在\(1\)号节点与当前节......
  • XDOJ 735 最小生成树 (Kruskal+并查集)
    标题最小生成树时间限制2S内存限制10000Kb问题描述:用克鲁斯卡尔(Kruskal)算法求无向网的最小生成树。输入:输入数据第一行为两个正整数n(1<n<=30)和m(1<m<100),分别表示顶点数和边数。后面紧跟m行数据,每行数据是一条边的信息,包括三个数字,分别表示该边的两个顶点和边上的权值......
  • 并查集模板(map保存负数下标)
    classSolution{unordered_map<int,int>fa,rank;voidinit(unordered_set&set){for(constauto&num:set){fa[num]=num;rank[num]=1;}}intfinds(intx){if(x!=fa[x]){fa[x]=finds(fa[x]);}returnfa[x];}voidunions(intx,inty){introotx=f......
  • 【唐叔学算法】第八天:并查集-图论连通性的大杀器
    你是否曾为如何高效地解决图论中的连通性问题而烦恼?并查集算法,就像一张无形的网,能帮你轻松连接所有节点。今天,就让我们一起揭开并查集算法的神秘面纱,探索它在Java编程中的应用。并查集是什么?并查集(Union-Find)是一种数据结构,用于处理一些不交集的合并及查询问题。它支持两......
  • 并查集学习笔记
    一、例题引入洛谷P3367【模板】并查集题目描述如题,现在有一个并查集,你需要完成合并和查询操作。输入格式第一行包含两个整数$N,M$,表示共有$N$个元素和$M$个操作。接下来$M$行,每行包含三个整数$Z_i,X_i,Y_i$。当$Z_i=1$时,将$X_i$与$Y_i$所在的集合合并。......
  • 每日一道算法题之并查集之移除最多的同行或同列石头
    importjava.util.HashMap;classSolution{publicstaticHashMap<Integer,Integer>row=newHashMap<>();publicstaticHashMap<Integer,Integer>col=newHashMap<>();publicstaticintMAXN=1001;publicstati......
  • 每日一道算法题之并查集之岛屿数量
    classSolution{publicstaticintMAXN=90001;publicstaticint[]f=newint[MAXN];publicstaticintn=0;publicstaticintunion_count=0;publicstaticbooleanisSameSet(inti,intj){returnfind(i)==find(j);......