首页 > 其他分享 >数据结构精选题

数据结构精选题

时间:2022-10-05 18:24:33浏览次数:75  
标签:ch 每个 fa int 染色 元素 精选 数据结构

P2391 白雪皑皑

题目大意

给定一个序列,\(m\)次染色,每次将一个区间内的点染色\(i\),染过色的元素可覆盖,求\(m\)次染色后,每个元素的颜色。

思路

性质:如果暴力染色的话,肯定T飞,那我们就看看时间消耗在了哪里?每个元素可能被多次染色。于是我们找性质,可以发现,每个元素的颜色肯定是最后一次被染上的颜色,于是我们倒着染色,这样就可以保证每个元素第一次被染上的颜色就是答案。那我们依旧是遍历整个区间,看谁没被染色的话就染上吗?那样和暴力有啥区别呢?因为每次染色是一段连续的区间,我们是不是可以用并查集来维护序列联通性呢?
\(fa[i]\)表示\(i\)之前第一个没被染色的元素(包括自己)。
这样我们就可以在染色区间上跳跃着染色,避免了依次经过染色的点所消耗的时间。
因为每个元素只会被染色一次,所以时间复杂度就是\(O(n)\)。

代码

点击查看代码
#include<iostream>
#include<cstdio>

using namespace std;
inline int read(){
	int w=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		w=w*10+ch-'0';
		ch=getchar();
	}
	return w*f;
}
int n,m,p,q,fa[1000005],col[1000005];
int get(int x){
	if(fa[x]==x) return x;
	return fa[x]=get(fa[x]);
}
int main(){
	n=read(),m=read(),p=read(),q=read();
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=m;i>=1;i--){
		int l=(i*p+q)%n+1,r=(i*q+p)%n+1;
		if(l>r) swap(l,r);
		for(int j=r;j>=l;){
			int t=get(j);
			if(t==j){
				col[j]=i;
				fa[j]=get(j-1);
			}
			j=fa[j];
		}
	}
	for(int i=1;i<=n;i++) cout<<col[i]<<"\n";
	return 0;
}
持续更新......

标签:ch,每个,fa,int,染色,元素,精选,数据结构
From: https://www.cnblogs.com/Jue-Qing/p/16756059.html

相关文章