Gym - 101911E Painting the Fence set

There is a beautiful fence near Monocarp's house. The fence consists of nn planks numbered from left to right. The ii-th plank has color aiai.

Monocarp's father have decided to give his son mm orders. Each order is a color cjcj. After each order Monocarp finds leftmost and rightmost planks currently having color cjcj and repaints all planks between them into color cjcj.

For example, if, at first, fence looked like (from left to right) [1,2,3,1,4,1,5,6][1,2,3,1,4,1,5,6], then after fulfilling an order with color 11 fence will look like [1,1,1,1,1,1,5,6][1,1,1,1,1,1,5,6].

Assume that Monocarp fulfills all orders in the order they come, one by one.

Note that if current order is about color xx and there is no more than one plank in the fence having color xx, then Monocarp doesn't repaint anything, so he can skip this order and skip to the next one.

Find out the color of each plank after Monocarp has done all the given orders.

Input

The first line contains one integer nn (1≤n≤3⋅105)(1≤n≤3⋅105) — the number of planks in the fence.

The second line contains nn space-separated integers a1,a2,…,ana1,a2,…,an (1≤ai≤3⋅105)(1≤ai≤3⋅105), where aiai is the initial color of the ii-th plank.

The third line contains one integer mm (1≤m≤3⋅105)(1≤m≤3⋅105) — the number of orders.

The fourth line contains mm space-separated integers c1,c2,…,cmc1,c2,…,cm (1≤cj≤3⋅105)(1≤cj≤3⋅105), where cjcj is the color of the jj-th order.

Output

Print nn space-separated integers — the colors of planks in the fence after processing all mm orders.

Examples

Input

4
1 2 1 2
2
2 1

Output

1 2 2 2 

Input

8
7 1 7 1 23 9 23 1
4
23 4 7 1

Output

7 7 7 1 1 1 1 1 

题意:n个数,m次操作,每次给出的数,要求这个数最左位置到最右的位置这个范围内都变成这个数,最后输出每个位置的数

题解:set记录下每个数的位置,每次操作一个数,把这个范围内的数的位置都去除,这个范围内只保留这个数首位,然后标记下这个数,说明这个数的范围已确定,并且这个范围没有其他数了,最后扫一遍每个数,确定下每个数在的位置即可,注意的是,只有这个数被标记了,也就是所在的区间全都是这个数,才能把这个区间都赋值为这个数。详见代码

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
set<int> s[N];
int a[N],vis[N];
int n,m;
int main()
{
	int x;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		s[a[i]].insert(i);
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&x);
		if(vis[x]) continue; // 已确定了 就不在操作 
		if(s[x].size()<2) // 若小于2个了 也不进行操作 
		{
			vis[x]=1;
			continue;
		}
		int l=*(s[x].begin()),r=*(s[x].rbegin());
		for(int j=l+1;j<=r-1;j++) // 把这个范围内的位置 全都去除 
		{
			s[a[j]].erase(j);
			while(vis[a[j]]&&s[a[j]].size()) // 若这个数被标记了 并且还有 继续去除  其实最多也就两个 首位置 和 尾位置 
			{
				j=*(s[a[j]].begin());
				s[a[j]].erase(j);
			}
		}
		vis[x]=1;
	}
	for(int i=1;i<=3e5;i++)
	{
		if(s[i].size()>=2&&vis[i]) // 只有被标记才可以操作区间 
		{
			int l=*(s[i].begin()),r=*(s[i].rbegin());
			for(int j=l;j<=r;j++)a[j]=i;
		}
	}
	for(int i=1;i<=n;i++) printf("%d%c",a[i]," \n"[i==n]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/85063931