ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

18th浙江省赛J

2022-03-30 23:33:26  阅读:170  来源: 互联网

标签:连通 ll 查集 fa 18th now 浙江省 op


18th浙江省赛J

G .Wall Game

不知道为啥这题在CF里这么奇怪

题目大意:

一个蜂窝状的地图,每一格是一个正六边形,两个格共用一条边则为相邻。

操作1表示占领 (x,y)。操作2表示查询(x,y)的连通块的边界长度

思路和代码:

一开始我也想并查集,但是有两个问题:

1)这是二维的,ai的范围还贼大,我本来还想开n2的表然后用一个pair表示每一个点,但是这样M会爆炸。

2)我不知道怎么去维护连通块的边界长度(没有想下去啊)。

在神牛队友潘的提醒下,我发现了题目说最多就n个点。又想到在线段树Trie中常用的给节点标号的做法。所以在占领新的坐标时,给其一个新的编号即可。但是还是因为xy太大,肯定是不能用二维数组的,所以可以用map。

再就是维护连通块边界的做法。

1)当两个块ab不连通,要给他并在一起的时候,我们发现最后大块的边界长度就是lena+lenb-2,至于为什么,自己动笔画几个8~

2)当两个块ab连通,我们发现要对大块直接-2,至于为什么,自己动笔画个图8~

ll n , m , idx ; 
ll ans[N] , fa[N] ;
map<pll , ll> mp ;

ll dx[6] = {1 , 1 , 0 , 0 , -1 , -1} ;
ll dy[6] = {-1 , 0 , -1 , 1 , 0 , 1} ;

ll find(ll now){
	return fa[now] = fa[now] == now ? now : find(fa[now]) ;
}

void solve(){
	ll op , x , y ;
	cin >> op >> x >> y ;
	if(op == 2){
		cout << ans[find(mp[{x , y}])] << "\n" ;
	}else{
		mp[{x , y}] = ++ idx ;
		fa[idx] = idx ;
		ans[idx] = 6 ;
		
		rep(i , 0 , 5){
			ll nx = x + dx[i] ;
			ll ny = y + dy[i] ;
			
			if(!mp[{nx , ny}]) continue ;
//			debug ;
			ll fnow = find(mp[{x , y}]) ;
			ll fnxt = find(mp[{nx , ny}]) ;
			
			if(fnxt == fnow) ans[fnow] -= 2 ;
			else{
				fa[fnxt] = fnow ;
				ans[fnow] += ans[fnxt] - 2 ;
			}
		}
	}
}//code_by_tyrii 
小结:

说实话这是我碰到最难的一个裸并查集种类并查集还是不会

1)省赛这样的正式比赛是一场马拉松,打了一两个小时很容易就疲惫了,这时候更要多动笔,像这题维护连通块边长的方法动动笔画一下很容易就能发现。

2)还有就是节点标号的处理,值得点赞。

3)千万不要怕繁琐!!!

标签:连通,ll,查集,fa,18th,now,浙江省,op
来源: https://www.cnblogs.com/tyriis/p/16079733.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有