2019 ICPC 徐州网络赛 B.so easy (并查集)
题目链接:https://nanti.jisuanke.com/t/41384
题目大意
给定n个数,从1到n排列,其中有q次操作,操作(1) 删除一个数字 // 操作(2)求这个数字之后第一个没有被删除的数字(包括自己)。
思路
本题就是考的并查集的路径压缩,让每一次find,可以达到O(1)级别,每次删除x的时候,把fa[x] = x+1即可,这样x+1如果也是被删除的,那么fa[x+1] = x+1,这样循环下去肯定会到达x后第一个没有被删除的,这个过程经过路径压缩之后,每一次询问就是O(1)了。
代码
#include<bits/stdc++.h> #define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define debug freopen("in.txt","r",stdin),freopen("out.txt","w",stdout); #define PI acos(-1) #define fs first #define sc second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 1e6+10; using namespace std; int N,Q; unordered_map<int,int> fa; inline void read(int &x){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); x = s*w; } int find(int x){ return fa.count(x)==0? x: fa[x] = find(fa[x]); } void join(int x,int y){ fa[x] = y; } int main(){ read(N),read(Q); while(Q--){ int op,x;read(op),read(x); if(op == 1){ join(x,x+1); }else{ printf("%d\n",find(x)); } } return 0; }