so easy
题意:
- 第一行两个数 n , q n,q n,q ,给一个数列 ( 1 , 2 , 3 , . . . , n ) (1,2,3,...,n) (1,2,3,...,n), q q q 组操作
- 接下来 q q q 行 每行两个数 z i z_i zi x i x_i xi, z i z_i zi( z = 1 z=1 z=1 or 2 2 2)为操作, x i x_i xi为操作位置
- 数据范围: ( 1 ≤ x < n < 1 0 9 , 1 ≤ q < 1 0 6 (1≤x<n<10^9,1 \leq q<10^6 (1≤x<n<109,1≤q<106 )
- z = = 1 z==1 z==1 : 删去 x x x
- z = = 2 z==2 z==2 : 输出从 x x x 位置开始,第一个还存在数列中的数
思路:
- 并查集(没想到吧)
- 删掉一个数,就把这个数
x
i
x_i
xi 和下一个数
x
i
+
1
x_{i+1}
xi+1 进行并查集
union(x,x+1)
- 但题目
n
n
n 的范围
1
e
9
1e9
1e9,显然不能用数组实现,所以这题需要用
map
模拟一下并查集。
我压根没往并查集去想,这个思路太妙了!
#include<map>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,q,op,x;
map<int,int> un;
int f(int i){
return un.count(i)?un[i]=f(un[i]):i;
}
void u(int i){
un[i]=f(i+1);
}
int main(){
scanf("%d%d",&n,&q);
while(q--){
scanf("%d%d",&op,&x);
if(op==1) u(x);
else printf("%d\n",f(x));
}
return 0;
}
/*
input
5 3
1 2
2 2
2 1
output
3
1
*/
附题解: