首页 > 其他分享 >CF1706E 题解

CF1706E 题解

时间:2024-02-08 20:02:19浏览次数:31  
标签:ch fa int 题解 mintim CF1706E 条边 define

你谷题目传送门

CF 题目传送门

题目大意

给定一个 \(n\) 个点 \(m\) 条边的无向图,询问 \(q\) 次,每次询问会指定两个正整数 \(l,r\),问要使对于 \(l \leq a \leq b \leq r\) 的所有 \(a,b\) 均有路径可以互相到达,最少需要加入前多少条边。

思路

考虑到每一次询问实质上就是问你在按顺序加了多少条边之后,编号 \([l,r]\) 之间的点都在同一个联通块中。

记 \(mintim(i)\) 表示 \(i\) 和 \(i+1\) 在加了 \(mintim(i)\) 条边之后处在同一个联通块,那么每一次询问的答案就是 \(\max_{i=l}^{r-1} mintim(i)\)。

在求解出所有的 \(mintim(i)\) 之后就可以直接用 ST 表或者线段树解决区间查询。

那么现在问题在于怎么求解 \(mintim(i)\)。

考虑顺序加边用启发式合并的思想处理 \(mintim(i)\),具体操作流程如下:

  • 当前要合并 \(x,y\) 所在的集合 \(S(x),S(y)\)。
  • 如果 \(|S(x)|<|S(y)|\),那么遍历 \(S(x)\) 中的每一个元素 \(p \in S(x)\),处理 \(mintim(p-1)\) 和 \(mintim(p)\)。
  • 否则交换 \(x,y\) 再操作即可。

不难看出每一个点在启发式合并的过程中最多被合并 \(\log_2 n\) 次,而并查集复杂度为 \(O(α(n))\),所以处理 \(mintim\) 的这一部分复杂度为 \(O(n \log_2 n α(n))\)。

总时间复杂度 \(O(n \log_2 n α(n)+q \log_2 n)\),可以通过本题。

#include<bits/stdc++.h>

#define RI register int
#define ll long long
#define ull unsigned long long
#define YES puts("YES")
#define NO puts("NO")

using namespace std;

namespace IO{
	inline int read(){
		RI X=0, W=0;register char ch=getchar();
		while(!isdigit(ch)) W|=ch=='-', ch=getchar();
		while(isdigit(ch)) X=(X<<1)+(X<<3)+(ch^48), ch=getchar();
		return W?-X:X;
	}
	inline void write(int x){
		if(x<0) x=-x, putchar('-');
		if(x>9) write(x/10);
		putchar(x%10+'0');
	}
}using namespace IO;

const int MAXN = 2e5+5;

int n, m, q;
int fa[MAXN];
int tree[MAXN << 2], minn[MAXN];
int siz[MAXN];

vector<int> G[MAXN];

inline int find(int x){
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}

inline void build(int p, int l, int r){
	if(l==r){
		tree[p]=minn[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid), build(p<<1|1,mid+1,r);
	tree[p]=max(tree[p<<1],tree[p<<1|1]);
}

inline int ask(int p, int l, int r, int L, int R){
	if(L>R) return 0;
	if(L<=l && r<=R) return tree[p];
	int mid=(l+r)>>1, res=0;
	if(L<=mid) res=ask(p<<1,l,mid,L,R);
	if(R>mid) res=max(res,ask(p<<1|1,mid+1,r,L,R));
	return res;
}

inline void solve(){
	//4 [space]
	n=read(),m=read(),q=read();int p;fa[n+1]=n+1;
	for(int i=1;i<=n;++i) G[i].clear(), G[i].push_back(i), fa[i]=i, siz[i]=1, minn[i]=1e9;
	for(int i=1;i<=m;++i) {
		int x, y;
		x=read(), y=read();
		x=find(x), y=find(y);
		if(x==y) continue;
		if(siz[x]>siz[y]) swap(x,y);
		siz[y]+=siz[x];fa[x]=y;
		for(int A=0;A<G[x].size();++A){
			p=G[x][A];
			if(find(p)==find(p+1)) minn[p]=min(i,minn[p]);
			if(find(p)==find(p-1)) minn[p-1]=min(minn[p-1],i);
			G[y].push_back(p);
		}
		G[x].clear();siz[x]=0;
	}
	build(1,1,n-1);
	while(q--){
		int l, r;
		l=read(), r=read();
		write(ask(1,1,n-1,l,r-1)), putchar(32);
	}
	putchar(10);
}

int main(){
	int t=read();
	while(t--) solve();
	return 0;
}

最后附上 评测记录

标签:ch,fa,int,题解,mintim,CF1706E,条边,define
From: https://www.cnblogs.com/OccasionalDreamer/p/18012074

相关文章

  • [COCI2007-2008#1] ZAPIS 题解
    题目传送门前置知识区间型动态规划思考过程这题也算是一道很经典的问题了(?)。看见\(n\leq200\),不难想到复杂度为\(O(n^3)\)的区间型动态规划。题面中有这么一段话。空串是规则括号序列。如果\(\textttA\)是规则括号序列,那么\(\texttt{(A)[A]{A}}\)都是规则括号......
  • CF1735D Meta-set 题解
    题目大意给定\(n\)张卡牌,每张卡牌有\(k\)个属性,第\(i\)张卡牌的第\(j\)个属性为\(c_{i,j}\)。一个由\(3\)张卡牌\(x,y,z\)组成的集合被称作好的,当且仅当对于\(1\leqi\leqk\)均有\(c_{x,i}=c_{y,i}=c_{z,i}\)或者\(c_{x,i},c_{y,i},c_{z,i}\)两两不相等。......
  • CF1793E Velepin and Marketing 题解
    题目大意有\(n\)个读者,第\(i\)年他们要一起读\(k_i\)本书,每一本书至少要让一个人读,每一个人也只能读恰好一本书。如果某一个人\(j\),如果有\(a_j\)个人这一年里和他读了同一本书,那么他就会感到满足。对于所有的\(q\)组询问,每组给定一个\(k_i\),求感到满足的人数的最......
  • CF1735E House Planning 题解
    题目大意一条直线上有\(n\)个房子和两个人,房子的坐标\(d_1,d_2,d_3\dotsd_n\),以及两个人坐标为\(p_1,p_2\)。现在会告诉你两个集合\(S_1=\{|p_1-d_i|,1\leqi\leqn\}\)以及\(S_2=\{|p_2-d_i|,1\leqi\leqn\}\)。这个写法可能不是很规范,但为了美观就写成这样了。......
  • CF1847E Triangle Platinum? 题解
    感谢@swiftc管理反馈的信息,对于题目大意确定的东西进行了完善。交互题。题目大意有一个长度为\(n\)的序列\(a\)满足\(1\leqa_i\leq4\),现在你可以进行不超过\(5500\)次询问,每次询问询问三个数\(1\leqi<j<k\leqn\),你将会得到\(a_i,a_j,a_k\)构成的三角形......
  • [ABC327G] Many Good Tuple Problems 题解
    Description对于一对长度均为\(M\)且元素值在\(\left[1,N\right]\)之间的序列\((S,T)\),定义其为好的当且仅当:存在一个长度为\(N\)的\(01\)序列\(X\),使得其满足如下条件:对于任意\(i\in\left[1,M\right]\),有\(X_{S_i}\neqX_{T_i}\)。给定\(N,M\),求在......
  • CF1918G Permutation of Given 题解
    总体思路本题通过每次在已知序列中加入\(2\)个元素的方法,可以构造出满足条件的序列\(A\),这里提供一种新的构造方法。性质因为序列\(A\)中所有元素构成的可重集与序列\(B\)中所有元素构成的可重集完全相等,所以\(A\)中所有元素之和与\(B\)中所有元素之和相等。\[\s......
  • SP277 CTGAME - City Game 题解
    题目传送门前置知识单调栈解法令\(f_{i,j}(1\lei\len,1\lej\lem)\)表示从\((1,j)\)到\((i,j)\)中以\((i,j)\)结尾的均为F的子串长度,即\((i,j)\)上面可延伸的最大距离(子矩形的长)。用单调栈的第一维存储子矩形的长,第二维存储子矩形的宽。考虑依次枚举每一......
  • qoj8171 Cola 题解
    题目链接点击打开链接题目解法很牛的题!!!会不了一点令\(pref_i\)表示第\(i\)轮知道了前缀\([1,...,i]\)考虑怎样的\(pref\)序列是合法的(即采用最优策略):\(pref_0=0\)\(\forall_{i\in[0,n-1]}\;pref_i\lepref_{i+1}\)\(pref\)中\(x\)的出现次数\(\len-x-1\),因......
  • [AGC021E] Ball Eat Chameleons 题解
    Description有\(n\)只变色龙,一开始都是蓝色。现在你喂了\(k\)次球,每次指定一只变色龙吃下你指定颜色的球。一只变色龙从蓝色变成红色当且仅当它吃的红球比蓝球多;一只变色龙从红色变成蓝色当且仅当它吃的蓝球比红球多。求最后能使所有变色龙都变成红色的方案数。两个方案......