计蒜客-so easy-离散化+并查集

Description

There are n points in an array with index from 1 to n, and there are two operations to those points.

1: 1 x marking the point x is not available

2: 2 x query for the index of the first available point after that point (including x itself) .

Input

n q
z1 ​x1
.
.
.
zq ​xq​

q is the number of queries, z is the type of operations, and x is the index of operations. 1≤x<n<1091≤q<106 and z is 1 or 2

Output

Output the answer for each query.

Sample Input

5 3
1 2
2 2
2 1

Sample Output

3
1

题目大意:

有n个点,标号从1~n。有q个操作,操作有两种:
1:1 x 使点x失效。
2:2 x 问从x开始,第一个有效点是哪个。

核心思想:

先将数据离散化
每个点的初始祖先都是自己。在点x失效之前将点x的祖先更新为点x+1的祖先,也就是f[x]=find(x+1)
此题充分体现出了并查集find函数在寻祖先时压缩路径的优点。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+20;
//en是离散后数组的大小,b数组用来离散化,f数组存祖先 
int en,b[N<<1],f[N<<1];
//存操作 
struct Node{
	int z,x;
}h[N];
//并查集寻祖先 
int find(int x)
{
	if(f[x]==x)
		return x;
	return f[x]=find(f[x]);
}
//离散映射 
int getid(int x)
{
	return lower_bound(b,b+en,x)-b+1;
}
int main()
{
	int n,q,ct=0;
	//输入 
	scanf("%d%d",&n,&q);
	for(int i=0;i<q;i++)
	{
		scanf("%d%d",&h[i].z,&h[i].x);
		b[ct++]=h[i].x;
		b[ct++]=h[i].x+1;
	}
	//离散 
	sort(b,b+ct);
	en=unique(b,b+ct)-b;
	//并查集初始化 
	for(int i=0;i<=en;i++)
		f[i]=i;
	//q次操作 
	for(int i=0;i<q;i++)
	{
		int t=getid(h[i].x);
		if(h[i].z==1)
			f[t]=find(t+1);
		else
			printf("%d\n",b[find(t)-1]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值