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

带权并查集板子

时间:2024-03-02 17:00:22浏览次数:23  
标签:dsu int sum 查集 long 板子 leq 带权 define

以一道区间和查询来说明板子如何使用

1.merge的时候只需要维护两个根节点的距离,利用的是合并时题目给的信息
2.find的时候更新维护是子节点到根的距离
3.需要加一个查询函数,因为距离数组是开在结构体内部的。

题目描述

对于一个长度为 \(N\) 的整数数列 \(A_{1}, A_{2}, \cdots A_{N}\),小蓝想知道下标 \(l\) 到 \(r\) 的部分和 \(\sum\limits_{i=l}^{r}A_i=A_{l}+A_{l+1}+\cdots+A_{r}\) 是多少?

然而,小蓝并不知道数列中每个数的值是多少,他只知道它的 \(M\) 个部分和的值。其中第 \(i\) 个部分和是下标 \(l_{i}\) 到 \(r_{i}\) 的部分和 \(\sum_{j=l_{i}}^{r_{i}}=A_{l_{i}}+A_{l_{i}+1}+\cdots+A_{r_{i}}\), 值是 \(S_{i}\) 。

对于所有评测用例, \(1 \leq N, M, Q \leq 10^{5},-10^{12} \leq S_{i} \leq 10^{12}, 1 \leq l_{i} \leq r_{i} \leq N\), \(1 \leq l \leq r \leq N\) 。数据保证没有矛盾。

蓝桥杯 2022 省赛 A 组 J 题。


#include <bits/stdc++.h>
using namespace std;
#define ll long long
# define int long long
#define ull unsigned long long
#define pii pair<int,int>

#define baoliu(x, y) cout << fixed << setprecision(y) << x
#define endl  "\n"
#define debug1(x) cerr<<x<<" "
#define  debug2(x) cerr<<x<<endl
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
int n, m;
int a[N];
struct DSU {
  vector<int> f, siz,d;
    
    DSU() {}
    DSU(int n) {
        init(n);
    }
    
    void init(int n) {
        f.resize(n);
        std::iota(f.begin(), f.end(), 0);
        siz.assign(n, 1);
        d.resize(n);
        for(int i=0;i<n;i++)d[i]=0;
    }
    
   int find(int x)
{
    if (f[x] != x)
    {
        int root = find(f[x]);
        d[x] += d[f[x]];//f[x]到根距离已经被更新
        f[x] = root;//让x指向根
    }
    return f[x];
}
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    
    bool merge(int l, int r,int add) {
        int x = find(l);
        int y = find(r);
        if (x == y) {
            return false;
        }
   d[y]=d[l]+add-d[r];
        siz[x] += siz[y];
        f[y] = x;
        return true;
    }
    
    int size(int x) {
        return siz[find(x)];
    }
  int  query(int u,int v){
    	int ans=d[v]-d[u];
    	return ans;
    }
};
void solve(){
	int q;
	cin>>n>>m>>q;
	DSU dsu(n+5);
	for(int i=1;i<=m;i++){
		int sum=0;
		int u,v;cin>>u>>v>>sum;
		u--;
		dsu.merge(u,v,sum);//根节点是最小值
	}
	for(int i=1;i<=q;i++){
		int u,v;cin>>u>>v;
		u--;
		if(dsu.same(u,v)){
		int ans=dsu.query(u,v);
		cout<<ans<<endl;
		}
		else {
			cout<<"UNKNOWN"<<endl;
		}
	}
}
signed main() {
    cin.tie(0);
    
    ios::sync_with_stdio(false);

    int t;
   //cin>>t;
     t=1;
    while (t--) {
solve();
    }
    return 0;
}

标签:dsu,int,sum,查集,long,板子,leq,带权,define
From: https://www.cnblogs.com/mathiter/p/18048859

相关文章

  • 程序自动分析—并查集
    Description在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件......
  • 信息传递(题解)[并查集]
    题目题目描述有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有......
  • 并查集(模板介绍+路径压缩)
    并查集(模板介绍+路径压缩)题面P3367并查集题目描述如题,现在有一个并查集,你需要完成合并和查询操作。第一行包含两个整数N,M,表示共有N个元素和M个操作。接下来M行,每行包含三个整数Z,X,Y。当Z=1时,将X与Y所在的集合合并。当Z=2时,输出Z与Y是否在同一集合内,是的输出Y;否则输出N......
  • 多项式板子
    #include<bits/stdc++.h>#defineullunsignedlonglongusingnamespacestd;constintN=262150,mod=998244353,g=3,invg=(mod+1)/3,inv2=(mod+1)/2;intrev[N];ulla[N],b[N],w[N],inv[N];intqpow(inta,intb){ intans=1; while(b){ if(b&1){ an......
  • SC的个人板子库
    声明Sugar_Cube的博客园主页宇宙安全声明本文包含了笔者常用的OI算法、数据结构的模板不保证正确,但能通过相应的模板题(如果有会挂出)如有错误请在评论区指出(虽然大抵没人看就是了)码风是笔者的个人习惯(能看懂就好喵),部分代码可能会省略快读Read()持续更新咕咕咕输入输出优化......
  • CF776D(并查集思想)
    难度1em还是一道比较套路的题目。观察发现,如果当\(r_{i}=1\)时他的两把钥匙状态是相同的,当\(r_{i}=0\)时他的两把钥匙状态是不同的,对于这种相同不同的问题可以考虑并差集,状态一样就一样的并在一起,否则就把不一样的并在一起所以以后看见这些问题(a=b+k,a=!b,a=b)都可以用带权并查......
  • 并查集+建图 同样是逆向思维 和星球大战类似
    L2-013红色警报分数25作者 陈越单位 浙江大学战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改......
  • 2024-02-24:用go语言,给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1, 同时还有一
    2024-02-24:用go语言,给你一个n个点的带权无向连通图,节点编号为0到n-1,同时还有一个数组edges,其中edges[i]=[fromi,toi,weighti],表示在fromi和toi节点之间有一条带权无向边,最小生成树(MST)是给定图中边的一个子集,它连接了所有节点且没有环,而且这些边的权值和最......
  • 并查集
    作用:1.将两个集合合并2.询问两个元素是否在一个集合当中基本原理:每个集合用一棵树来表示,树根的编号就是整个集合的编号。每个节点存储它的父节点,p[x]表示x的父节点操作:1.判断树根:if(p[x]==x);2.求x的集合编号:while(p[x]!=x)x=p[x];3.如何合并两个集合:p[x]是x的集合编......
  • ABC302Ex Ball Collector (可撤销并查集)
    由于博客园存在关站风险,文章以后同步发在这里,可能会有更好的阅读体验。首先我们分析一下,如果我们已经知道了要走哪些点,我们可以怎么做。考虑将\(a_i,b_i\)之间连边,发现题目可以被转化为给定一个图,要求对于每条边将其一个顶点染色,问最多能将多少个点染色。于是我们对于每个连......