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;
}