Examples
input
Copy
7
1 3
1 1
2 1 2
1 2
1 1
1 2
2 1 3
output
3 2 2 3 2
题意:输入一个数字q,接下来q行按格式输入,“1 x”的格式表示给队列添加数字x,“2 x y”表示把队列中所有x变成y。最后输出该数列。
算法:DFS,DSU(题目标签是这个,但好像没有用到)
问题:想到一些思路,但受限于时间没有联系起来
思路:看完数据的数量级,就知道不能暴力做。当时我有想到两个大致的思路,一个是将改变数字的信息先保存起来,最后再处理;另外就是从后往前做。但最后都没有实现完整的思路。那么,首先说从后往前处理有什么好处,很显然如果实现的话,复杂度会从原本的n^2变成n。每次的“2 x y”将整个数列分成若干块,从最后一块往前看,每块的规则数从一开始递增的,所以我们只需要把规则保存下来,到新的一块的更新规则,再按规则对该块数列元素处理即可。又因为写出的规则数是小于5*10^5的,所以开个数组保存就行了,数组下标为x,元素值为y,每次更新把相应下标的元素改变就行了。
代码:ac
#include<bits/stdc++.h>
using namespace std;
#define N 500010
int q[N], to[N], len, x[N], y[N], type, n;
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &type, &x[i]);
if (type == 2) scanf("%d", &y[i]);
}
for (int i = 1; i <= 500001; i++) to[i] = i;/*初始化规则,即不改变*/
for (int i = n; i; i--)
{
if (!y[i]) q[++len] = to[x[i]];/*y[i]==0时代表是“1 x”类型,按照规则添加并改变即可*/
else to[x[i]] = to[y[i]];/*到新数列段,更新规则*/
}
for (int i = len; i; i--) printf("%d ", q[i]);/*注意最后倒序输出*/
return 0;
}