Problem:
Score : 2000 points

Problem Statement

You are given a permutation P_1 ... P_N of the set {1, 2, ..., N}.

You can apply the following operation to this permutation, any number of times (possibly zero):

Choose two indices i,j (1 ≦ i < j ≦ N), such that j - i ≧ K and |P_i - P_j| = 1.
Then, swap the values of P_i and P_j.

Among all permutations that can be obtained by applying this operation to the given permutation, find the lexicographically smallest one.

Constraints

2≦N≦500,000

1≦K≦N-1

P is a permutation of the set {1, 2, ..., N}.

Input

The input is given from Standard Input in the following format:

N K
P_1 P_2 ... P_N

Output

Print the lexicographically smallest permutation that can be obtained.

Sample Input 1

4 2
4 2 3 1

Sample Output 1

2
1
4
3

One possible way to obtain the lexicographically smallest permutation is shown below:

4 2 3 1

4 1 3 2

3 1 4 2

2 1 4 3

Sample Input 2

5 1
5 4 3 2 1

Sample Output 2

1
2
3
4
5

Sample Input 3

8 3
4 5 7 8 3 1 2 6

Sample Output 3

1
2
6
7
5
3
4
8

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N (500000+1000)
#define INF (10000000)
using namespace std;

struct Edge{int to,next;}edge[N<<2];
int n,k,a[N],pos[N],Segt[N<<2];
int head[N],num_edge,Ind[N];
priority_queue<int,vector<int>,greater<int> >q;

void add(int u,int v)
{
	edge[++num_edge].to=v;
	edge[num_edge].next=head[u];
	head[u]=num_edge;
	Ind[v]++;
}

void Build(int now,int l,int r)
{
	if (l==r){Segt[now]=INF; return;}
	int mid=(l+r)>>1;
	Build(now<<1,l,mid); Build(now<<1|1,mid+1,r);
	Segt[now]=min(Segt[now<<1],Segt[now<<1|1]);
}

int Query(int now,int l,int r,int l1,int r1)
{
	if (r<l1 || l>r1) return INF;
	if (l1<=l && r<=r1) return Segt[now];
	int mid=(l+r)>>1;
	return min(Query(now<<1,l,mid,l1,r1),Query(now<<1|1,mid+1,r,l1,r1));
}

void Update(int now,int l,int r,int x,int k)
{
	if (l==r) {Segt[now]=k; return;}
	int mid=(l+r)>>1;
	if (x<=mid) Update(now<<1,l,mid,x,k);
	else Update(now<<1|1,mid+1,r,x,k);
	Segt[now]=min(Segt[now<<1],Segt[now<<1|1]);
}

void Toposort()
{
	int cnt=0;
	for (int i=1; i<=n; ++i) if (!Ind[i]) q.push(i);
	while (!q.empty())
	{
		int x=q.top(); q.pop(); a[x]=++cnt;
		for (int i=head[x]; i; i=edge[i].next)
		{
			Ind[edge[i].to]--;
			if (!Ind[edge[i].to]) q.push(edge[i].to);
		}
	}
	for(int i=1; i<=n; ++i) printf("%d\n",a[i]);
}

int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1; i<=n; ++i)
		scanf("%d",&a[i]),pos[a[i]]=i;;
	Build(1,1,n);
	for (int i=n; i>=1; --i)
	{
		int x=Query(1,1,n,pos[i]+1,min(pos[i]+k-1,n));
		if (x!=INF) add(pos[i],pos[x]);
		int y=Query(1,1,n,max(pos[i]-k+1,1),pos[i]-1);
		if (y!=INF) add(pos[i],pos[y]);
		Update(1,1,n,pos[i],i);
	}
	Toposort();
}