数字替换

数字替换

http://oj.daimayuan.top/course/10/problem/731#tab-custom-test

维护一个数列,这个数列初始为空。

对于这个数列,总共有 q 次操作,每次操作分为如下两个种类:

\(1\ x\),意为在数列末尾加一个数字

\(2\ x\ y\),意为将当前数列中所有值为 x 的数的值替换成 y。

请在 q 次操作后,输出这个数列。

输入格式

第 1 行一个数字 q,表示有 q 个操作。

第 2 行至 q+1 行每行输入一个操作。

输出格式

一行,表示最后得到的数列。

样例输入

7
1 3
1 1
2 1 2
1 2
1 1
1 2
2 1 3

样例输出

3 2 2 3 2

数据规模

\(1\leq q,x,y\leq 5 \times 10^5\)

题目分析

数组模拟链表。

\(head_i\)表示以\(i\)为值的数,其中的\(top\ and\ end\)表示以其为值的下标。

维护好\(head\),实现好增加和修改两个操作即可。

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+7;
int a[N];
int ans[N];
struct Head {
	int top;
	int end;
	bool vis;
} head[N];

void add(int n,int x) {
	if(!head[x].vis)
		head[x].top = n;
	head[x].vis = 1;
	a[head[x].end] = n;
	head[x].end = n;
}

void quary(int x,int y) {
	if(x==y)
		return;
	if(!head[x].vis)
		return ;
	if(!head[y].vis)
		head[y] = head[x];
	else {
		a[head[y].end] = head[x].top;
		head[y].end = head[x].end;
	}
	head[x].vis = 0;
	head[x].top = 0;
	head[x].end = 0;
}

int main() {
	int q,n=0;
	cin>>q;
	while(q--) {
		int type;
		scanf("%d",&type);
		if(type == 1) {
			n++;
			int x;
			scanf("%d",&x);
			add(n,x);
		} else {
			int x,y;
			scanf("%d%d",&x,&y);
			quary(x,y);
		}
	}
	for(int i = 1 ; i <= N ; i++) {
		if(head[i].top) {
			int x = head[i].top;
			while(x) {
				ans[x] = i;
				x = a[x];
			}
		}
	}
	for(int i = 1 ; i <= n ; i++)
		printf("%d ",ans[i]);
}
posted @ 2022-04-11 00:30  seekerHeron  阅读(196)  评论(0)    收藏  举报