#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<utility>
#include<sstream>
#include<stack>
using namespace std ;

//#ifndef ONLINE_JUDGE++++
    //freopen("input.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
//#endif

#define pb push_back
#define all(x) x.begin(),x.end()
#define distSqr(x1,y1,z1,x2,y2,z2) (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)
#define dist(x1,y1,x2,y2) sqrt(distSqr(x1,y1,x2,y2))
#define Set(x,v) memset(x,v,sizeof x)
#define lb lower_bound
#define ub upper_bound
#define gcd(a,b) __gcd(a,b)
#define pi acos(-1)
#define mp make_pair
#define pos first
#define val second
#define error 1e-12
#define mod 1000007
#define For(i,n) for(i=0;i<n;i++)
#define inf 1e5

typedef long long ll;
typedef unsigned int ui;

typedef pair<ui,ui> puu;
typedef double db;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,db> pid;
typedef vector<int> VI;
typedef pair<char,char> pcc;

bool chk(int n,int pos) {return n&(1<<pos);}
void set(int& n,int pos) {n=n|(1<<pos);}
void reset(int& n,int pos) {n=n&~(1<<pos);}

const int mx=(1<<19)+1;
int tree[mx],a[200010];

void build(int i,int s,int e)
{
    tree[i]=e-s+1;
    if(s==e) return ;
    int l=(i<<1),r=l+1,mid=(s+e)>>1;
    build(l,s,mid);
    build(r,mid+1,e);
}

int query(int i,int s,int e,int p,int sum)
{
    tree[i]--;
    if(s==e) return s;
    int l=(i<<1),r=l+1,mid=(s+e)>>1;
    if(sum+tree[l]>=p) return query(l,s,mid,p,sum);
    else return query(r,mid+1,e,p,sum+tree[l]);
}

int value(int i,int s,int e,int v)
{
    if(s>v) return 0;
    if(e<=v) return tree[i];
    int l=(i<<1),r=l+1,mid=(s+e)>>1;
    return value(l,s,mid,v)+value(r,mid+1,e,v);
}

int main()
{
    int i,j,k,n;
    scanf("%d",&n);
        build(1,0,n-1);
        for(i=n-1;i>=0;i--)
        {
            scanf("%d",&k);
            int t=value(1,0,n-1,k);
            a[i]=t-1;
            query(1,0,n-1,t,0);
        }
        build(1,0,n-1);
        for(i=n-1;i>=0;i--)
        {
            scanf("%d",&k);
            int t=value(1,0,n-1,k);
            a[i]+=t-1;
            query(1,0,n-1,t,0);
        }
        //for(i=n-1;i>=0;i--) printf("%d ",a[i]); printf("\n");
        for(i=0;i<n;i++)
        {
            if(a[i]>i)
            {
                a[i]-=(i+1);
                a[i+1]++;
            }
        }
        //for(i=n-1;i>=0;i--) printf("%d ",a[i]); printf("\n");
        build(1,0,n-1);
        for(i=n-1;i>=0;i--)
        {
            a[i]=query(1,0,n-1,a[i]+1,0);
        }
        //for(i=n-1;i>=0;i--) printf("%d ",a[i]); printf("\n");
        bool flag=0;
        for(i=n-1;i>=0;i--)
        {
            if(flag) printf(" ");
            flag=true;
            printf("%d",a[i]);
        }
        printf("\n");
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int v[200005],b[200005],t[200005],a[200005],x[200005],y[200005],now[200005],n;
int lowbit(int x)
{
	return x&(-x);
}
void Update(int x,int v)
{
	for (int i=x;i<=n;i+=lowbit(i))
		t[i]+=v;
}
int Getsum(int x)
{
	int ans=0;
	for (int i=x-1;i;i-=lowbit(i))
		ans+=t[i];
	return ans;
}
int Get(int k)
{
	int l=1,r=n;
	while (l!=r)
	{
		int m=(l+r)>>1;
		int p=Getsum(m);
		if (p==k)
		{
			if (!v[m]) return m;
			else l=m+1;
			continue;
		}
		if (p<k) l=m;
		else r=m;
	}
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]++;
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),b[i]++;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		x[i]=Getsum(a[i]),Update(a[i],-1);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		y[i]=Getsum(b[i]),Update(b[i],-1);
	for (int i=n;i>1;i--)
	{
		now[i]=now[i]+x[i]+y[i];
		if (now[i]>n-i) now[i]=now[i]-n+i-1,now[i-1]++;
	}
	now[1]=now[1]+x[1]+y[1];
	if (now[1]>=n) now[1]-=n;
	printf("%d ",now[1]);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		v[i]=0;
	v[now[1]+1]=1;
	Update(now[1]+1,-1);
	for (int i=2;i<n;i++)
	{
		int x=Get(now[i]);
		printf("%d ",x-1);
		Update(x,-1);
		v[x]=1;
	}
	for (int i=1;i<=n;i++)
		if (!v[i])
		{
			cout<<i-1<<endl;
			return 0;
		}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int v[200005],b[200005],t[200005],a[200005],x[200005],y[200005],now[200005],n;
int lowbit(int x)
{
	return x&(-x);
}
void Update(int x,int v)
{
	for (int i=x;i<=n;i+=lowbit(i))
		t[i]+=v;
}
int Getsum(int x)
{
	int ans=0;
	for (int i=x-1;i;i-=lowbit(i))
		ans+=t[i];
	return ans;
}
int Find(int x)
{
	int now=x;
	while (now<=n)
	{
		if (v[now]) now++;
		return now;
	}
}
int Get(int k)
{
	int l=1,r=n;
	while (l!=r)
	{
		int m=(l+r)>>1;
		int p=Getsum(m);
		if (p==k)
		{
			if (!v[m]) return m;
			else return Find(m);
		}
		if (p<k) l=m;
		else r=m;
	}
	if (!v[l]) return l;
	return Find(l);
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]++;
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),b[i]++;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		x[i]=Getsum(a[i]),Update(a[i],-1);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		y[i]=Getsum(b[i]),Update(b[i],-1);
	for (int i=n;i>1;i--)
	{
		now[i]=now[i]+x[i]+y[i];
		if (now[i]>n-i) now[i]=now[i]-n+i-1,now[i-1]++;
	}
	now[1]=now[1]+x[1]+y[1];
	if (now[1]>=n) now[1]-=n;
	printf("%d ",now[1]);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		v[i]=0;
	v[now[1]+1]=1;
	Update(now[1]+1,-1);
	for (int i=2;i<n;i++)
	{
		int x=Get(now[i]);
		printf("%d ",x-1);
		Update(x,-1);
		v[x]=1;
	}
	for (int i=1;i<=n;i++)
		if (!v[i])
		{
			cout<<i-1<<endl;
			return 0;
		}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int v[200005],b[200005],t[200005],a[200005],x[200005],y[200005],now[200005],n;
int lowbit(int x)
{
	return x&(-x);
}
void Update(int x,int v)
{
	for (int i=x;i<=n;i+=lowbit(i))
		t[i]+=v;
}
int Getsum(int x)
{
	int ans=0;
	for (int i=x-1;i;i-=lowbit(i))
		ans+=t[i];
	return ans;
}
int Find(int x)
{
	int now=x;
	while (x)
	{
		if (v[x]) x--;
		return x;
	}
	while (now<=n)
	{
		if (v[now]) now++;
		return now;
	}
}
int Get(int k)
{
	int l=1,r=n;
	while (l!=r)
	{
		int m=(l+r)>>1;
		int p=Getsum(m);
		if (p==k)
		{
			if (!v[m]) return m;
			else return Find(m);
		}
		if (p<k) l=m;
		else r=m;
	}
	if (!v[l]) return l;
	return Find(l);
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]++;
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),b[i]++;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		x[i]=Getsum(a[i]),Update(a[i],-1);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		y[i]=Getsum(b[i]),Update(b[i],-1);
	for (int i=n;i>1;i--)
	{
		now[i]=now[i]+x[i]+y[i];
		if (now[i]>n-i) now[i]=now[i]-n+i-1,now[i-1]++;
	}
	now[1]=now[1]+x[1]+y[1];
	if (now[1]>=n) now[1]-=n;
	printf("%d ",now[1]);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	v[now[1]+1]=1;
	Update(now[1]+1,-1);
	for (int i=2;i<n;i++)
	{
		int x=Get(now[i]);
		printf("%d ",x-1);
		Update(x,-1);
		v[x]=1;
	}
	for (int i=1;i<=n;i++)
		if (!v[i])
		{
			cout<<i-1<<endl;
			return 0;
		}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int v[200005],b[200005],t[200005],a[200005],x[200005],y[200005],now[200005],n;
int lowbit(int x)
{
	return x&(-x);
}
void Update(int x,int v)
{
	for (int i=x;i<=n;i+=lowbit(i))
		t[i]+=v;
}
int Getsum(int x)
{
	int ans=0;
	for (int i=x-1;i;i-=lowbit(i))
		ans+=t[i];
	return ans;
}
int Get(int k)
{
	int l=1,r=n;
	while (1)
	{
		int m=(l+r)>>1;
		int p=Getsum(m);
		if (p==k)
		{
			if (!v[m]) return m;
			else l=m+1;
			continue;
		}
		if (p<k) l=m;
		else r=m;
	}
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]++;
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),b[i]++;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		x[i]=Getsum(a[i]),Update(a[i],-1);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		y[i]=Getsum(b[i]),Update(b[i],-1);
	for (int i=n;i>1;i--)
	{
		now[i]=now[i]+x[i]+y[i];
		if (now[i]>n-i) now[i]=now[i]-n+i-1,now[i-1]++;
	}
	now[1]=now[1]+x[1]+y[1];
	if (now[1]>=n) now[1]-=n;
	printf("%d ",now[1]);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		v[i]=0;
	v[now[1]+1]=1;
	Update(now[1]+1,-1);
	for (int i=2;i<n;i++)
	{
		int x=Get(now[i]);
		printf("%d ",x-1);
		Update(x,-1);
		v[x]=1;
	}
	for (int i=1;i<=n;i++)
		if (!v[i])
		{
			cout<<i-1<<endl;
			return 0;
		}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int v[200005],b[200005],t[200005],a[200005],x[200005],y[200005],now[200005],n;
int lowbit(int x)
{
	return x&(-x);
}
void Update(int x,int v)
{
	for (int i=x;i<=n;i+=lowbit(i))
		t[i]+=v;
}
int Getsum(int x)
{
	int ans=0;
	for (int i=x-1;i;i-=lowbit(i))
		ans+=t[i];
	return ans;
}
/*int Get(int k)
{
	int l=1,r=n;
	while (1)
	{
		int m=(l+r)>>1;
		int p=Getsum(m);
		if (p==k)
		{
			if (!v[m]) return m;
			else l=m+1;
			continue;
		}
		if (p<k) l=m;
		else r=m;
	}
}*/
int Get(int k)
{
	int ans=0,now=0;
	for (int i=20;i>=0;i--)
		if (ans+(1<<i)>n||now+t[ans+(1<<i)]>=k)
			continue;
	    else
		{
			now+=t[ans+(1<<i)];
			ans+=(1<<i);
		}
	return ans+1;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]++;
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),b[i]++;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		x[i]=Getsum(a[i]),Update(a[i],-1);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		y[i]=Getsum(b[i]),Update(b[i],-1);
	for (int i=n;i>1;i--)
	{
		now[i]=now[i]+x[i]+y[i];
		if (now[i]>n-i) now[i]=now[i]-n+i-1,now[i-1]++;
	}
	now[1]=now[1]+x[1]+y[1];
	if (now[1]>=n) now[1]-=n;
	printf("%d ",now[1]);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	v[now[1]+1]=1;
	Update(now[1]+1,-1);
	for (int i=2;i<=n;i++)
	{
		int x=Get(now[i]+1);
		printf("%d ",x-1);
		Update(x,-1);
		v[x]=1;
	}
	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <vector>
#include <map>
#include <string.h>

using namespace std;

int A[200000],B[200000];
int tree[200010]={0};
int sorted[200000];
int ans[200005];

void update(int idx, int val,int n)
{
    while (idx <= n)
    {
        tree[idx] += val;
        idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0)
    {
        sum += tree[idx];
        idx -= (idx & -idx);
    }
    return sum;
}

void countsmall(int P[],int n,int small[])
{
    int i;
    for (i=0;i<=n;++i)
        tree[i]=0;
    for (i=0;i<n;++i)
        sorted[P[i]]=i+1;
    for (i=0;i<n;++i)
    {
        small[sorted[i]-1]=read(sorted[i]);
        update(1,1,n);
        update(sorted[i],-1,n);
    }
}
int smallA[200010],smallB[200010];
int sum[200010]={0};
int main()
{
    int n;
    scanf ("%d",&n);
    int i;
    for (i=0;i<n;++i)
        scanf ("%d",&A[i]);
    for (i=0;i<n;++i)
        scanf ("%d",&B[i]);
    countsmall(A,n,smallA);
    countsmall(B,n,smallB);
    int carry=0;
    int base=2;
    int pos=n-2;
    sum[pos]=(smallA[pos]+smallB[pos])%base;
    carry=(smallA[pos]+smallB[pos])/base;
    pos--;
    base++;
    while (pos>=0)
    {
        sum[pos]=(smallA[pos]+smallB[pos]+carry)%base;
        carry=(smallA[pos]+smallB[pos]+carry)/base;
        pos--;
        base++;
    }
    //for (i=0;i<n;++i)
    //    printf("%d ",sum[i]);
    //printf("\n");
    memset(tree,0,200010*sizeof(int));
    for (i=1;i<=n;++i)
        update(i,1,n);
    int ans[200005];
    int left,right,mid;
    for (i=0;i<n;++i)
    {
        left=1;
        right=n;
        while (left<=right)
        {
            //printf("%d %d\n",left,sum[i]);
            mid=(left+right)/2;
            int x=read(mid)-1;
            if (x<sum[i])
                left=mid+1;
            else
                right=mid-1;
        }
        ans[i]=left-1;
        update(left,-1,n);
    }
    for (i=0;i<n;++i)
        printf("%d ",ans[i]);
    return 0;
}


#include <stdio.h>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

int A[200000],B[200000];
int tree[200010]={0};
vector< pair<int,int> > v;

void update(int idx, int val,int n)
{
    while (idx <= n)
    {
        tree[idx] += val;
        idx += (idx & -idx);
    }
}

int read(int idx)
{
    int sum = 0;
    while (idx > 0)
    {
        sum += tree[idx];
        idx -= (idx & -idx);
    }
    return sum;
}

void countsmall(int P[],int n,int small[])
{
    int i;
    for (i=0;i<=n;++i)
        tree[i]=0;
    v.clear();
    for (i=1;i<=n;++i)
        v.push_back(pair<int,int>(P[i-1],i));
    sort(v.begin(),v.end());
    for (i=0;i<n;++i)
    {
        small[v[i].second-1]=read(v[i].second);
        update(1,1,n);
        update(v[i].second,-1,n);
    }
}
int smallA[200010],smallB[200010];
int sum[200010]={0};
int main()
{
    int n;
    scanf ("%d",&n);
    int i;
    for (i=0;i<n;++i)
        scanf ("%d",&A[i]);
    for (i=0;i<n;++i)
        scanf ("%d",&B[i]);
    countsmall(A,n,smallA);
    countsmall(B,n,smallB);
    int carry=0;
    int base=2;
    int pos=n-2;
    sum[pos]=(smallA[pos]+smallB[pos])%base;
    carry=(smallA[pos]+smallB[pos])/base;
    pos--;
    base++;
    while (pos>=0)
    {
        sum[pos]=(smallA[pos]+smallB[pos]+carry)%base;
        carry=(smallA[pos]+smallB[pos]+carry)/base;
        pos--;
        base++;
    }
    //for (i=0;i<n;++i)
    //    printf("%d ",sum[i]);
    //printf("\n");
    map<int,int> ma;
    for (i=0;i<n;++i)
        ma[i]=i;
    int ans[100005];
    for (i=0;i<n;++i)
    {
        vector<pair <int,int> > V(ma.begin(),ma.end());
        ans[i]=V[sum[i]].second;
        //printf("%d ",sum[i]);
        ma.erase(V[sum[i]].second);
    }
    for (i=0;i<n;++i)
        printf("%d ",ans[i]);
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
ll mpow(ll a, ll n,ll mod)
{ll ret=1;ll b=a;while(n) {if(n&1)
    ret=(ret*b)%mod;b=(b*b)%mod;n>>=1;}
return (ll)ret;
}
using namespace std;
#define mem(x,a) memset(x,a,sizeof(x))
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
using namespace std;
#define N (int)2e5+5
int tr[4*N],tri[4*N];
int cnt[N],n;
void build(int idx,int l,int r){
    if(l==r){
        tr[idx]=1;
        tri[l]=idx;
        return;
    }
    int mid=(l+r)>>1;
    build(2*idx,l,mid);
    build(2*idx+1,mid+1,r);
    tr[idx]=tr[2*idx]+tr[2*idx+1];
}
int finp(int idx,int l,int r,int x){
    if(l>x)
       return 0;
    if(r<=x)
       return tr[idx];
    int mid=(l+r)>>1;
    return finp(2*idx,l,mid,x)+finp(2*idx+1,mid+1,r,x);
}
void rem(int x){
    int idx=tri[x];
    tr[idx]=0;
    while(idx>1){
        idx=(idx)/2;
        tr[idx]=tr[2*idx]+tr[2*idx+1];
    }
}
void ord(vector<int>& a){
    build(1,0,n-1);
    for(int i=0;i<n;i++){
        int x=finp(1,0,n-1,a[i])-1;
        cnt[n-i-1]+=x;
        rem(a[i]);
    }
}
int kth(int idx,int l,int r,int x){
    if(l==r){
        return l;
    }
    int mid=(l+r)>>1;
    if(tr[2*idx]>=x)
       return kth(2*idx,l,mid,x);
    else
        return kth(2*idx+1,mid+1,r,x-tr[2*idx]);
}
int main(){
    cin>>n;
    vector<int> a(n),b(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=0;i<n;i++){
        cin>>b[i];
    }
    ord(a);
    ord(b);
    //int car=0;
    vector<int> fin;
    for(int i=0;i<n;i++){
        int x=cnt[i]/(i+1);
        cnt[i+1]+=x;
        cnt[i]-=(x)*(i+1);
    }
    for(int i=0;i<n;i++){
        fin.pb(cnt[n-1-i]);
    }
    build(1,0,n-1);
    for(int i=0;i<fin.size();i++){
        int x=kth(1,0,n-1,fin[i]+1);
        rem(fin[i]);
        cout<<x<<" ";
    }
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
ll mpow(ll a, ll n,ll mod)
{ll ret=1;ll b=a;while(n) {if(n&1)
    ret=(ret*b)%mod;b=(b*b)%mod;n>>=1;}
return (ll)ret;
}
using namespace std;
#define mem(x,a) memset(x,a,sizeof(x))
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
using namespace std;
#define N (int)2e5+5
int tr[4*N],tri[4*N];
int cnt[N],n;
void build(int idx,int l,int r){
    if(l==r){
        tr[idx]=1;
        tri[l]=idx;
        return;
    }
    int mid=(l+r)>>1;
    build(2*idx,l,mid);
    build(2*idx+1,mid+1,r);
    tr[idx]=tr[2*idx]+tr[2*idx+1];
}
int finp(int idx,int l,int r,int x){
    if(l>x)
       return 0;
    if(r<=x)
       return tr[idx];
    int mid=(l+r)>>1;
    return finp(2*idx,l,mid,x)+finp(2*idx+1,mid+1,r,x);
}
void rem(int x){
    int idx=tri[x];
    tr[idx]=0;
    while(idx>1){
        idx=(idx)/2;
        tr[idx]=tr[2*idx]+tr[2*idx+1];
    }
}
void ord(vector<int>& a){
    build(1,0,n-1);
    for(int i=0;i<n;i++){
        int x=finp(1,0,n-1,a[i])-1;
        cnt[n-i-1]+=x;
        rem(a[i]);
    }
}
int kth(int idx,int l,int r,int x){
    if(l==r){
        return l;
    }
    int mid=(l+r)>>1;
    if(tr[2*idx]>=x)
       return kth(2*idx,l,mid,x);
    else
        return kth(2*idx+1,mid+1,r,x-tr[2*idx]);
}
int main(){
    cin>>n;
    vector<int> a(n),b(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=0;i<n;i++){
        cin>>b[i];
    }
    ord(a);
    ord(b);
    int car=0;
    vector<int> fin;
    for(int i=0;i<n;i++){
        int x=cnt[i]/(i+1);
        cnt[i+1]+=x;
        cnt[i]-=(x)*(i+1);
    }
    for(int i=0;i<n;i++){
        fin.pb(cnt[n-1-i]);
    }
    build(1,0,n-1);
    for(int i=0;i<fin.size();i++){
        int x=kth(1,0,n-1,fin[i]+1);
        rem(x);
        cout<<x<<" ";
    }
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<map>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
inline int lowbit(int x){return x&(-x);};
int n,A[200005];
typedef struct
{
	int c[200005];
	void clear() {memset(c,0,sizeof(c));}
	void add(int x,int a){	for(int i=x;i<=n+2;i+=lowbit(i)) c[i]+=a;}
	int query(int x)
	{
		int ret=0;
		for(int i=x;i>0;i-=lowbit(i)) ret+=c[i];
		return ret;
	}
}BiT;
BiT T;
bool judge(int x,int ord)
{
	int a=T.query(x+2);
	return x-a>=ord;
}
int BS(int l,int r,int ord)
{
	if(r-l<=1)
	{
		if(judge(l,ord)) return l;
		return r;
	}
	int m=(l+r)/2;
	if(judge(m,ord)) return BS(l,m,ord);
	return BS(m+1,r,ord);
}
int main()
{
	cin>>n;
	int x;
	for(int i=n-1;i>=0;i--)
	{
		scanf("%d",&x);
		int a=T.query(x+2);
		A[i]+=x-a;
		T.add(x+2,1);
	}
	T.clear();
	for(int i=n-1;i>=0;i--)
	{
		scanf("%d",&x);
		int a=T.query(x+2);
		A[i]+=x-a;
		T.add(x+2,1);
	}
	for(int i=1;i<=n-1;i++)
	{
		if(i!=n-1) A[i+1]+=A[i]/(i+1);
		A[i]%=(i+1);
	}
	T.clear();
	for(int i=n-1;i>=0;i--)
	{
		int a=BS(0,n-1,A[i]);
		printf("%d",a);
		if(i!=0) printf(" ");
		T.add(a+2,1);
	}
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<map>
#include<iostream>
#include<queue>
using namespace std;
inline int lowbit(int x){return x&(-x);};
int n,A[200005];
typedef struct
{
	int c[200005];
	void clear() {memset(c,0,sizeof(c));}
	void add(int x,int a){	for(int i=x;i<=n+2;i+=lowbit(i)) c[i]+=a;}
	int query(int x)
	{
		int ret=0;
		for(int i=x;i>0;i-=lowbit(i)) ret+=c[i];
		return ret;
	}
}BiT;
BiT T;
bool judge(int x,int ord)
{
	int a=T.query(x+2);
	return x-a>=ord;
}
int BS(int l,int r,int ord)
{
	if(r-l<=1)
	{
		if(judge(l,ord)) return l;
		return r;
	}
	int m=(l+r)/2;
	if(judge(m,ord)) return BS(l,m,ord);
	return BS(m+1,r,ord);
}
int main()
{
	cin>>n;
	int x;
	for(int i=n-1;i>=0;i--)
	{
		scanf("%d",&x);
		int a=T.query(x+2);
		A[i]+=x-a;
		T.add(x+2,1);
	}
	T.clear();
	for(int i=n-1;i>=0;i--)
	{
		scanf("%d",&x);
		int a=T.query(x+2);
		A[i]+=x-a;
		T.add(x+2,1);
	}
	for(int i=1;i<=n-1;i++)
	{
		if(i!=n-1) A[i+1]+=A[i]/(i+1);
		A[i]%=(i+1);
	}
	T.clear();
	for(int i=n-1;i>=0;i--)
	{
		int a=BS(0,n-1,A[i]);
		printf("%d",a);
		if(i!=0) printf(" ");
		T.add(a+2,1);
	}
	printf("\n");
	return 0;
}


#include <stdio.h>
#include <string.h>
#define maxn 200001
int n, cnt[200005], L, R, pos, ans, v, sum[900000], add[900000];

void set_up(int i, int l, int r)
{
    if (L <= l && r <= R)    add[i] += v;
    else
    {
        int mid = (l + r) >> 1;
        if(L <= mid)    set_up(i << 1, l, mid);
        if(R > mid)    set_up((i << 1) + 1, mid + 1, r);
    }
    sum[i] = (r == l ? 0 : sum[i << 1] + sum[(i << 1)+1]);
    sum[i] += add[i] * (r - l + 1);
}

void query(int i, int l, int r, int addv)
{
    if(l == r)    {ans = sum[i] + addv;    return;}
    int mid = (l + r) >> 1;
    if(pos <= mid)    query(i << 1, l, mid, addv + add[i]);
    else              query((i << 1) + 1, mid + 1, r, addv + add[i]);
}

void find(int i, int l, int r, int k)
{
    if(l == r)    {ans = l;    return;}
    int mid = (l + r) >> 1;
    if(k <= sum[i << 1])    find(i << 1, l, mid, k);
    else                    find((i << 1) + 1, mid + 1, r, k - sum[i << 1]);
}

void scan(int* x)
{
    memset(add, 0, sizeof(add));
    memset(sum, 0, sizeof(sum));
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", x + i);
        L = R = x[i] + 1;
        v = x[i];
        set_up(1, 1, n);
    }
    for(int i = 1; i <= n; i++)
    {
        pos = x[i] + 1;
        query(1, 1, n, add[1]);
        cnt[i] += ans;    L = x[i] + 2;    R = n;
        if(L > R)    continue;
        v = -1;
        set_up(1, 1, n);
    }
}

int main()
{
    static int a[maxn], b[maxn];
    scanf("%d", &n);
    scan(a);    scan(b);
    for(int i = n; i >= 1; i--)
        if(cnt[i] > n - i)
        {
            cnt[i - 1]++;
            cnt[i] -= (n - i + 1);
        }
    memset(add, 0, sizeof(add));
    memset(sum, 0, sizeof(sum));
    for(int i = 1; i <= n; i++)
    {
        v = 1;    L = R = i;
        set_up(1, 1, n);
    }
    for(int i = 1; i <= n; i++)
    {
        find(1, 1, n, cnt[i] + 1);
        printf("%d ", ans - 1);
        L = R = ans;    v = -1;
        set_up(1, 1, n);
    }
    return 0;
}


#include <stdio.h>
#include <string.h>
int n, cnt[200005], L, R, pos, ans, v, sum[900000], add[900000];

void set_up(int i, int l, int r)
{
    if (L <= l && r <= R)    add[i] += v;
    else
    {
        int mid = (l + r) >> 1;
        if(L <= mid)    set_up(i << 1, l, mid);
        if(R > mid)    set_up((i << 1) + 1, mid + 1, r);
    }
    sum[i] = (r == l ? 0 : sum[i << 1] + sum[(i << 1)+1]);
    sum[i] += add[i] * (r - l + 1);
}

void query(int i, int l, int r, int addv)
{
    if(l == r)    {ans = sum[i] + addv;    return;}
    int mid = (l + r) >> 1;
    if(pos <= mid)    query(i << 1, l, mid, addv + add[i]);
    else              query((i << 1) + 1, mid + 1, r, addv + add[i]);
}

void find(int i, int l, int r, int k)
{
    if(l == r)    {ans = l;    return;}
    int mid = (l + r) >> 1;
    if(k <= sum[i << 1])    find(i << 1, l, mid, k);
    else                    find((i << 1) + 1, mid + 1, r, k - sum[i << 1]);
}

void scan(int* x)
{
    memset(add, 0, sizeof(add));
    memset(sum, 0, sizeof(sum));
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", x + i);
        L = R = x[i] + 1;
        v = x[i];
        set_up(1, 1, n);
    }
    for(int i = 1; i <= n; i++)
    {
        pos = x[i] + 1;
        query(1, 1, n, add[1]);
        cnt[i] += ans;    L = x[i] + 2;    R = n;
        if(L > R)    continue;
        v = -1;
        set_up(1, 1, n);
    }
}

int main()
{
    static int a[200005], b[200005];
    scanf("%d", &n);
    scan(a);    scan(b);
    for(int i = n; i >= 1; i--)
        if(cnt[i] > n - i)
        {
            cnt[i - 1]++;
            cnt[i] -= (n - i + 1);
        }
    memset(add, 0, sizeof(add));
    memset(sum, 0, sizeof(sum));
    for(int i = 1; i <= n; i++)
    {
        v = 1;    L = R = i;
        set_up(1, 1, n);
    }
    for(int i = 1; i <= n; i++)
    {
        find(1, 1, n, cnt[i] + 1);
        printf("%d ", ans - 1);
        L = R = ans;    v = -1;
        set_up(1, 1, n);
    }
    return 0;
}


#include <bits/stdc++.h>

#define gc getchar
#define pc putchar

using namespace std;

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

#define vi vector<int>
#define si set<int>
#define vs vector<string>
#define pii pair<int,int>
#define vpi vector<pii>
#define pri priority_queue<int>
#define rev_pri priority_queue<int,vector<int>,greater<int> >
#define mpi map<int,int>
#define i64 long long int
#define endl '\n'
#define pi acos(-1)
#define all(v) v.begin(),v.end()
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define For(i,n) for(int i=0;i<n;i++)
#define Rep(i,x,y) for(int i=x;i<=y;i++)
#define eps 1e-8
#define ff first
#define ss second
#define mem(a,b) memset(a,b,sizeof(a))
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define READ freopen("input.txt", "r", stdin)
#define sz size()
#define dbg(x) printf("yo is %d!\n",x)
#define dbg2(x,y) printf("yo is %d! and %d!\n",x,y)
#define foreach(i,c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define sqr(a) (a) * (a)
#define clr clear()
#define CASE(a) printf("Case %d: ",a)
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)

//int dx[] = {0,1,0,-1};
//int dy[] = {1,0,-1,0};
//int dx[] = { -1, -1,  0, 1, 1, 1,  0, -1 };
//int dy[] = {  0, -1, -1, -1,  0, 1, 1, 1 };
//int dxK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
//int dyK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };

//functions

//i64 gcd(i64 a,i64 b){if(!b)return a;return gcd(b,a%b);}

//inline void fastRead(i64 *a){register char c=0;while(c<33)c=gc();*a=0;while(c>33){*a=*a*10+c-'0';c=gc();}}

//inline void fastWrite(int a){char snum[20];int i=0;do{snum[i++]=a%10+48;a=a/10;}while(a!=0);i=i-1;while(i>=0)pc(snum[i--]);pc('\n');}

//i64 bigmod(i64 num,i64 n){if(!n)return 1;i64 x=(bigmod(num,n/2)*bigmod(num,n/2))%mod;if(n%2)x=(x*num)%mod;return x;}

//i64 modinverse(i64 num){return bigmod(num,mod-2);}

//void combination(int pos,int last){if(pos==k+1){for(int i=1;i<=k;i++)cout << tem[i];cout << endl;return;}
//for(int i=last+1;i<=n-k+pos;i++){tem[pos] = num[i-1];combination(pos+1,i);}}
//i64 power(i64 value, i64 base){i64 result = 1;For(i,base)result *= value;return result;}
//int Set(int N,int pos){return N = (1<<pos);}
//int reset(int N,int pos){return N &= (~(1<<pos));}
//bool check(int N,int pos){return (bool)(N & (1<<pos));}

typedef tree< int, null_type, less < int >, rb_tree_tag, tree_order_statistics_node_update > Set;

Set s;
int n, u, a[200002];

int read(){
    for(int i = 0; i < n; i++)
        s.insert(i);
    for(int i = 0; i < n; i++)
    {
        cin >> u;
        a[n-i-1] += s.order_of_key(u);
        s.erase(u);
    }
}

int main()
{
    cin >> n;
    read();
    read();
    cout << endl;
    for(int i = 0; i < n; i++)
    {
        a[i+1] += a[i]/(i+1);
        a[i]   %= i+1;
    }
    cout << endl;
    for(int i = 0; i < n; i++)
        s.insert(i);
    for(int i = n-1; i >=0; i--){
        cout << *s.find_by_order(a[i]) << " ";
        s.erase(s.find_by_order(a[i]));
    }
    return 0;
}


#include <bits/stdc++.h>

#define gc getchar
#define pc putchar

using namespace std;

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

#define vi vector<int>
#define si set<int>
#define vs vector<string>
#define pii pair<int,int>
#define vpi vector<pii>
#define pri priority_queue<int>
#define rev_pri priority_queue<int,vector<int>,greater<int> >
#define mpi map<int,int>
#define i64 long long int
#define endl '\n'
#define pi acos(-1)
#define all(v) v.begin(),v.end()
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define For(i,n) for(int i=0;i<n;i++)
#define Rep(i,x,y) for(int i=x;i<=y;i++)
#define eps 1e-8
#define ff first
#define ss second
#define mem(a,b) memset(a,b,sizeof(a))
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define READ freopen("input.txt", "r", stdin)
#define sz size()
#define dbg(x) printf("yo is %d!\n",x)
#define dbg2(x,y) printf("yo is %d! and %d!\n",x,y)
#define foreach(i,c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define sqr(a) (a) * (a)
#define clr clear()
#define CASE(a) printf("Case %d: ",a)
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)

//int dx[] = {0,1,0,-1};
//int dy[] = {1,0,-1,0};
//int dx[] = { -1, -1,  0, 1, 1, 1,  0, -1 };
//int dy[] = {  0, -1, -1, -1,  0, 1, 1, 1 };
//int dxK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
//int dyK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };

//functions

//i64 gcd(i64 a,i64 b){if(!b)return a;return gcd(b,a%b);}

//inline void fastRead(i64 *a){register char c=0;while(c<33)c=gc();*a=0;while(c>33){*a=*a*10+c-'0';c=gc();}}

//inline void fastWrite(int a){char snum[20];int i=0;do{snum[i++]=a%10+48;a=a/10;}while(a!=0);i=i-1;while(i>=0)pc(snum[i--]);pc('\n');}

//i64 bigmod(i64 num,i64 n){if(!n)return 1;i64 x=(bigmod(num,n/2)*bigmod(num,n/2))%mod;if(n%2)x=(x*num)%mod;return x;}

//i64 modinverse(i64 num){return bigmod(num,mod-2);}

//void combination(int pos,int last){if(pos==k+1){for(int i=1;i<=k;i++)cout << tem[i];cout << endl;return;}
//for(int i=last+1;i<=n-k+pos;i++){tem[pos] = num[i-1];combination(pos+1,i);}}
//i64 power(i64 value, i64 base){i64 result = 1;For(i,base)result *= value;return result;}
//int Set(int N,int pos){return N = (1<<pos);}
//int reset(int N,int pos){return N &= (~(1<<pos));}
//bool check(int N,int pos){return (bool)(N & (1<<pos));}

typedef tree< int, null_type, less < int >, rb_tree_tag, tree_order_statistics_node_update > Set;

Set s;
int n, u, a[200002];

int read(){
    for(int i = 0; i < n; i++)
        s.insert(i);
    for(int i = 0; i < n; i++)
    {
        cin >> u;
        a[n-i-1] += s.order_of_key(u);
        s.erase(u);
    }
}

int main()
{
    cin >> n;
    read();
    read();
    for(int i = 0; i < n; i++)
    {
        a[i+1] += a[i]/(i+1);
        a[i]   %= i+1;
    }
    for(int i = 0; i < n; i++)
        s.insert(i);
    for(int i = n-1; i >=0; i--){
        cout << *s.find_by_order(a[i]) << " ";
        s.erase(s.find_by_order(a[i]));
    }
    return 0;
}


#include<cstdio>
#include<cstring>
#define read(num) scanf("%d",&num)
using namespace std;
const int Maxn = 200000+10;
int n,a[Maxn],b[Maxn],f[Maxn];

int c[Maxn];
#define lowbit(x) (x & -x)
void upd(int x,int val){
	for(int i = x; i <= n; i += lowbit(x))c[i] += val;
}
int sum(int x){
	int ret = 0;
	for(int i = x;i >= 1;i -= lowbit(x))ret += c[i];
	return ret;
}
void init(){
	memset(c,0,sizeof(c));
	for(int i = 1;i <= n;i++)upd(i,1);
}

int main()
{
	read(n);
	for(int i = 1;i <= n;i++){read(a[i]);a[i] ++;}
	for(int i = 1;i <= n;i++){read(b[i]);b[i] ++;}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(a[i] - 1);
		f[n - i] += les;
		upd(a[i],-1);
	}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(b[i] - 1);
		f[n - i] += les;
		upd(b[i],-1);
	}
	for(int i = 1;i < n;i++){
		f[i+1] += f[i] / (i+1);
		f[i] = f[i] % (i+1);
	}
	init();
	int sml = 1;
	for(int i = n-1; i >= 1;i--){
		int l = 1,r = n,mid,tmp,ans = -1;
		while( l <= r){
			mid = (l + r)>>1;
			tmp = sum(mid - 1);
			if(tmp <= f[i]){
				l = mid + 1;
				ans = mid;
			}
			else r = mid -1;
		}
		if(ans == -1)ans = sml;
		printf("%d ", ans - 1);
		upd(ans,-1);
		while(!c[sml])sml ++;
	}
	for(int i=1; i<=n; i++)
        if(c[i]){
            printf("%d\n", i-1);
            break;
        }
    return 0;
}


#include<cstdio>
#include<cstring>
#define read(num) scanf("%d",&num)
using namespace std;
const int Maxn = 200000+10;
int n,a[Maxn],b[Maxn],f[Maxn];

int c[Maxn];
#define lowbit(x) (x & -x)
void upd(int x,int val){
	for(int i = x; i <= n; i += lowbit(i))c[i] += val;
}
int sum(int x){
	int ret = 0;
	for(int i = x;i;i -= lowbit(i))ret += c[i];
	return ret;
}
void init(){
	memset(c,0,sizeof(c));
	for(int i = 1;i <= n;i++)upd(i,1);
}

int main()
{
	read(n);
	for(int i = 1;i <= n;i++){read(a[i]);a[i] ++;}
	for(int i = 1;i <= n;i++){read(b[i]);b[i] ++;}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(a[i] - 1);
		f[n - i] += les;
		upd(a[i],-1);
	}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(b[i] - 1);
		f[n - i] += les;
		upd(b[i],-1);
	}
	for(int i = 1;i < n;i++){
		f[i+1] += f[i] / (i+1);
		f[i] = f[i] % (i+1);
	}
	init();
	int sml = 1;
	for(int i = n-1; i >= 1;i--){
		int l = 1,r = n,mid,tmp,ans = -1;
		while( l <= r){
			mid = (l + r)>>1;
			tmp = sum(mid - 1);
			if(tmp <= f[i]){
				l = mid + 1;
				ans = mid;
			}
			else r = mid -1;
		}
		if(ans == -1)ans = sml;
		printf("%d ", ans - 1);
		upd(ans,-1);
		while(!c[sml])sml ++;
	}
	for(int i=1; i<=n; i++)
        if(c[i]){
            printf("%d\n", i-1);
            break;
        }
    return 0;
}


#include<cstdio>
#include<cstring>
#define lowbit(x) (x & -x)
#define read(num) scanf("%d",&num)
using namespace std;
const int Maxn = 200000+10;
int n,c[Maxn];
int a[Maxn],b[Maxn],f[Maxn];
void upd(int x,int val){
	for(int i = x; i <= n; i += lowbit(x))c[i] += val;
}
int sum(int x){
	int ret = 0;
	for(int i = x;i;i -= lowbit(x))ret += c[i];
	return ret;
}
void init(){
	memset(c,0,sizeof(c));
	for(int i = 1;i <= n;i++)upd(i,1);
}
int main()
{
	read(n);
	for(int i = 1;i <= n;i++){read(a[i]);a[i] ++;}
	for(int i = 1;i <= n;i++){read(b[i]);b[i] ++;}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(a[i] - 1);
		f[n - i] += les;
		upd(a[i],-1);
	}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(b[i] - 1);
		f[n - i] += les;
		upd(b[i],-1);
	}
	for(int i = 1;i < n;i++){
		f[i+1] = f[i]/(i+1);
		f[i] = f[i]%(i+1);
	}
	init();
	int sml = 1;
	for(int i = n-1; i >= 1;i--){
		int l = 1,r = n,mid,tmp,ans = -1;
		while( l <= r){
			mid = (l + r)>>1;
			tmp = sum(mid - 1);
			if(tmp <= f[i]){
				l = mid + 1;
				ans = mid;
			}
			else r = mid -1;
		}
		if(ans == -1)ans = sml;
		printf("%d ", ans - 1);
		upd(ans,-1);
		while(!c[sml])sml ++;
	}
	for(int i=1; i<=n; i++)
        if(c[i]){
            printf("%d\n", i-1);
            break;
        }
    return 0;
}


#include<cstdio>
#include<cstring>
#define read(num) scanf("%d",&num)
using namespace std;
const int Maxn = 200000+10;
int n,a[Maxn],b[Maxn],f[Maxn];

int c[Maxn];
#define lowbit(x) (x & -x)
void upd(int x,int val){
	for(int i = x; i <= n; i += lowbit(x))c[i] += val;
}
int sum(int x){
	int ret = 0;
	for(int i = x;i;i -= lowbit(x))ret += c[i];
	return ret;
}
void init(){
	memset(c,0,sizeof(c));
	for(int i = 1;i <= n;i++)upd(i,1);
}

int main()
{
	read(n);
	for(int i = 1;i <= n;i++){read(a[i]);a[i] ++;}
	for(int i = 1;i <= n;i++){read(b[i]);b[i] ++;}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(a[i] - 1);
		f[n - i] += les;
		upd(a[i],-1);
	}
	init();
	for(int i = 1;i < n;i++){
		int les = sum(b[i] - 1);
		f[n - i] += les;
		upd(b[i],-1);
	}
	for(int i = 1;i < n;i++){
		f[i+1] += f[i] / (i+1);
		f[i] = f[i] % (i+1);
	}
	init();
	int sml = 1;
	for(int i = n-1; i >= 1;i--){
		int l = 1,r = n,mid,tmp,ans = -1;
		while( l <= r){
			mid = (l + r)>>1;
			tmp = sum(mid - 1);
			if(tmp <= f[i]){
				l = mid + 1;
				ans = mid;
			}
			else r = mid -1;
		}
		if(ans == -1)ans = sml;
		printf("%d ", ans - 1);
		upd(ans,-1);
		while(!c[sml])sml ++;
	}
	for(int i=1; i<=n; i++)
        if(c[i]){
            printf("%d\n", i-1);
            break;
        }
    return 0;
}


#include <cstdio>
#include <cstring>

int tree[1000000];
int g[300000],h[300000];
int i,n,t;

struct Tree_Array
{
	int g[300000];
	inline void clear()
	{
		memset(g,0,sizeof(g));
		return;
	}
	inline void add(int x)
	{
		for (int i=x;i<=n;i=i+(i&(-i)))
			g[i]++;
		return;
	}
	inline int ask(int x)
	{
		int s=0;
		for (int i=x;i!=0;i=i-(i&(-i)))
			s=s+g[i];
		return s;
	}
};

Tree_Array T;

inline void buildtree(int l,int r,int node)
{
	tree[node]=r-l+1;
	if (l!=r)
	{
		int mid=(l+r)>>1;
		buildtree(l,mid,node<<1);
		buildtree(mid+1,r,node<<1|1);
	}
	return;
}

inline int asktree(int k)
{
	int l=0,r=n-1,mid,node=1;
	while (l<r)
	{
		mid=(l+r)>>1;
		if (tree[node<<1]>=k)
			tree[node]--,r=mid,node=node<<1;
		else
			tree[node]--,k=k-tree[node<<1],l=mid+1,node=node<<1|1;
	}
	tree[node]--;
	return l;
}

inline int fastscanf()
{
	int t=0;
	char c=getchar();
	while (! ((c>47) && (c<58)))
		c=getchar();
	while ((c>47) && (c<58))
		t=t*10+c-48,c=getchar();
	return t;
}

inline void fastprintf(int x)
{
	if (! x)
		putchar('0');
	else
	{
		char c[8];
		for (c[0]=0;x;x=x/10)
			c[0]++,c[c[0]]=x%10;
		for (;c[0]>0;c[0]--)
			putchar(c[c[0]]+48);
	}
	putchar(' ');
	return;
}

int main()
{
	n=fastscanf();
	T.clear();
	for (i=1;i<=n;i++)
		g[i]=fastscanf();
	for (i=n;i>0;i--)
	{
		t=g[i]+1;
		h[i]=h[i]+T.ask(t);
		T.add(t);
	}
	T.clear();
	for (i=1;i<=n;i++)
		g[i]=fastscanf();
	for (i=n;i>0;i--)
	{
		t=g[i]+1;
		h[i]=h[i]+T.ask(t);
		T.add(t);
	}
	for (i=n;i>0;i--)
		while (h[i]>=n-i+1)
			h[i]=h[i]-(n-i+1),h[i-1]++;
	buildtree(0,n-1,1);
	for (i=1;i<=n;i++)
		g[i]=asktree(h[i]+1);
	for (i=1;i<=n;i++)
		fastprintf(g[i]);
	return 0;
}


#include <cstdio>
#include <cstring>

int tree[1000000];
int g[300000],h[300000];
int i,n,t;

struct Tree_Array
{
	int g[300000];
	inline void clear()
	{
		memset(g,0,sizeof(g));
		return;
	}
	inline void add(int x)
	{
		for (int i=x;i<=n;i=i+(i&(-i)))
			g[i]++;
		return;
	}
	inline int ask(int x)
	{
		int s=0;
		for (int i=x;i!=0;i=i-(i&(-i)))
			s=s+g[i];
		return s;
	}
};

Tree_Array T;

inline void buildtree(int l,int r,int node)
{
	tree[node]=r-l+1;
	if (l!=r)
	{
		int mid=(l+r)>>1;
		buildtree(l,mid,node<<1);
		buildtree(mid+1,r,node<<1|1);
	}
	return;
}

inline int asktree(int k)
{
	int l=0,r=n-1,mid,node=1;
	while (l<r)
	{
		mid=(l+r)>>1;
		if (tree[node<<1]>=k)
			tree[node]--,r=mid,node=node<<1;
		else
			tree[node]--,k=k-tree[node<<1],l=mid+1,node=node<<1|1;
	}
	tree[node]--;
	return l;
}

int main()
{
	scanf("%d",&n);
	T.clear();
	for (i=1;i<=n;i++)
		scanf("%d",&g[i]);
	for (i=n;i>0;i--)
	{
		t=g[i]+1;
		h[i]=h[i]+T.ask(t);
		T.add(t);
	}
	T.clear();
	for (i=1;i<=n;i++)
		scanf("%d",&g[i]);
	for (i=n;i>0;i--)
	{
		t=g[i]+1;
		h[i]=h[i]+T.ask(t);
		T.add(t);
	}
	for (i=n;i>0;i--)
		while (h[i]>=n-i+1)
			h[i]=h[i]-(n-i+1),h[i-1]++;
	buildtree(0,n-1,1);
	for (i=1;i<=n;i++)
		g[i]=asktree(h[i]+1);
	for (i=1;i<=n;i++)
		printf("%d ",g[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define M 1000000007
#define F first
#define S second
#define mp make_pair
#define pb push_back
#define gcd __gcd
#define in(a) scanf("%d",&a)
#define in2(a,b) scanf("%d%d",&a,&b)
#define in3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc(ch) scanf("%c",&ch)
#define pr(n) printf("%d ",n)
#define out(n) printf("%d\n",n)
#define cf(n) printf("%I64d\n",n)
#define yes printf("YES\n")
#define no printf("NO\n")
#define lin printf("\n")
#define dbg(v,n) for(i=0;i<n;i++)pr(v[i]); lin
#define ck printf("continue\n")
#define ii pair<int,int>
#define vi vector<int>
#define vii vector<pair<int,int> >
#define vvi vector<vector<int> >
#define viii vector<pair<pair<int,int>,int> >
#define vvii vector<vector<pair<int,int> > >
#define st(vec) sort(vec.begin(),vec.end())
#define lp(i,a,b) for(i=a;i<b;i++)
#define N 200005
int bit[N];
void update(int j,int n)
{
    for(;j<=n;j+=j&(-j))
        bit[j]++;
}
int query(int j)
{
    int x=0;
    for(;j>0;j-=(j)&(-j))
        x+=bit[j];
    return x;
}
int main()
{
    int i,n,c;
    in(n);
    vi va(n),vb(n);
    for(i=n-1;i>=0;i--)
        in(va[i]),va[i]++;
    for(i=n-1;i>=0;i--)
        in(vb[i]),vb[i]++;
    vi v1(n),v2(n),v(n),vis(n+1,0),ans(n,0);
    for(i=0;i<n;i++)
    {
        v1[i]=query(va[i]);
        update(va[i],n);
    }
    fill(bit,bit+N,0);
    for(i=0;i<n;i++)
    {
        v2[i]=query(vb[i]);
        update(vb[i],n);
    }
    c=0;
    for(i=0;i<n;i++)
    {
        c+=(v1[i]+v2[i]);
        v[i]=c%(i+1);
        c/=(i+1);
    }
    reverse(v.begin(),v.end());
    fill(bit,bit+N,0);
    lp(i,0,n)
        v[i]++;
    lp(i,0,n)
    {
        c=v[i]+query(v[i]);
        while(vis[c])
            c++;
        ans[i]=c-1,vis[c]=1;
        update(c,n);
    }
    dbg(ans,n);

}


#include<bits/stdc++.h>
using namespace std;
#define M 1000000007
#define F first
#define S second
#define mp make_pair
#define pb push_back
#define gcd __gcd
#define in(a) scanf("%d",&a)
#define in2(a,b) scanf("%d%d",&a,&b)
#define in3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc(ch) scanf("%c",&ch)
#define pr(n) printf("%d ",n)
#define out(n) printf("%d\n",n)
#define cf(n) printf("%I64d\n",n)
#define yes printf("YES\n")
#define no printf("NO\n")
#define lin printf("\n")
#define dbg(v,n) for(i=0;i<n;i++)pr(v[i]); lin
#define ck printf("continue\n")
#define ii pair<int,int>
#define vi vector<int>
#define vii vector<pair<int,int> >
#define vvi vector<vector<int> >
#define viii vector<pair<pair<int,int>,int> >
#define vvii vector<vector<pair<int,int> > >
#define st(vec) sort(vec.begin(),vec.end())
#define lp(i,a,b) for(i=a;i<b;i++)
#define N 200005
int bit[N],ar[4*N],pos[N];
void update(int j,int n)
{
    for(;j<=n;j+=j&(-j))
        bit[j]++;
}
int query(int j)
{
    int x=0;
    for(;j>0;j-=(j)&(-j))
        x+=bit[j];
    return x;
}
void build(int l,int h,int p)
{
    ar[p]=h-l+1;
    int m=(l+h)/2;
    if(l==h)
        pos[l]=p;
    else
    {
        build(l,m,2*p);
        build(m+1,h,2*p+1);
    }
    return ;
}
int seg(int k,int l,int h,int p)
{
    if(ar[p]==h-l+1)
        return l+k-1;
    int m=(l+h)/2;
    if(ar[2*p]>=k)
        return seg(k,l,m,2*p);
    else
        return seg(k-ar[2*p],m+1,h,2*p+1);
}
void up(int p)
{
    while(p>0)
        ar[p]--,p/=2;
    return ;
}
int main()
{
    int i,n,c;
    in(n);
    vi va(n),vb(n);
    for(i=n-1;i>=0;i--)
        in(va[i]),va[i]++;
    for(i=n-1;i>=0;i--)
        in(vb[i]),vb[i]++;
    vi v1(n),v2(n),v(n),ans(n,0);
    for(i=0;i<n;i++)
    {
        v1[i]=query(va[i]);
        update(va[i],n);
    }
    fill(bit,bit+N,0);
    for(i=0;i<n;i++)
    {
        v2[i]=query(vb[i]);
        update(vb[i],n);
    }
    c=0;
    for(i=0;i<n;i++)
    {
        c+=(v1[i]+v2[i]);
        v[i]=c%(i+1);
        c/=(i+1);
    }
    reverse(v.begin(),v.end());
    fill(bit,bit+N,0);
    lp(i,0,n)
        v[i]++;
    build(0,n-1,1);
    lp(i,0,n)
    {
        c=seg(v[i],0,n-1,1);
        ans[i]=c;
        up(pos[c]);
    }
    dbg(ans,n);
}


#include<bits/stdc++.h>
using namespace std;
#define M 1000000007
#define F first
#define S second
#define mp make_pair
#define pb push_back
#define gcd __gcd
#define in(a) scanf("%d",&a)
#define in2(a,b) scanf("%d%d",&a,&b)
#define in3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc(ch) scanf("%c",&ch)
#define pr(n) printf("%d ",n)
#define out(n) printf("%d\n",n)
#define cf(n) printf("%I64d\n",n)
#define yes printf("YES\n")
#define no printf("NO\n")
#define lin printf("\n")
#define dbg(v,n) for(i=0;i<n;i++)pr(v[i]); lin
#define ck printf("continue\n")
#define ii pair<int,int>
#define vi vector<int>
#define vii vector<pair<int,int> >
#define vvi vector<vector<int> >
#define viii vector<pair<pair<int,int>,int> >
#define vvii vector<vector<pair<int,int> > >
#define st(vec) sort(vec.begin(),vec.end())
#define lp(i,a,b) for(i=a;i<b;i++)
#define N 200005
int bit[N];
void update(int j,int n)
{
    for(;j<=n;j+=j&(-j))
        bit[j]++;
}
int query(int j)
{
    int x=0;
    for(;j>0;j-=(j)&(-j))
        x+=bit[j];
    return x;
}
int main()
{
    int i,n,c;
    in(n);
    vi va(n),vb(n);
    for(i=n-1;i>=0;i--)
        in(va[i]),va[i]++;
    for(i=n-1;i>=0;i--)
        in(vb[i]),vb[i]++;
    vi v1(n),v2(n),v(n),vis(n+1,0),ans(n,0);
    for(i=0;i<n;i++)
    {
        v1[i]=query(va[i]);
        update(va[i],n);
    }
    fill(bit,bit+N,0);
    for(i=0;i<n;i++)
    {
        v2[i]=query(vb[i]);
        update(vb[i],n);
    }
    c=0;
    for(i=0;i<n;i++)
    {
        c+=(v1[i]+v2[i]);
        v[i]=c%(i+1);
        c/=(i+1);
    }
    reverse(v.begin(),v.end());
    fill(bit,bit+N,0);
    set<int> s;
    set<int> :: iterator itr;
    lp(i,0,n)
        v[i]++,s.insert(i+1);
    lp(i,0,n)
    {
        c=v[i]+query(v[i]);
        itr=lower_bound(s.begin(),s.end(),c);
        c=*itr;
        ans[i]=c-1,vis[c]=1;
        update(c,n),s.erase(c);
    }
    dbg(ans,n);

}


#include<cstdio>
#include<cstring>
const int N=2e5+5;
int n,m,i,v[N],f[N],a[N];
inline int read(){
	char c=getchar();int k=0;for (;c<48||c>57;c=getchar());
	for (;c>47&&c<58;c=getchar()) k=(k<<3)+(k<<1)+c-48;return k;
}
inline void write(int x){if (x>9) write(x/10);putchar(x%10+48);}
inline void add(int x){for (;x<=n;x+=x&-x) f[x]++;}
inline void dec(int x){for (;x<=n;x+=x&-x) f[x]--;}
inline int sum(int x){int k=0;for (;x;x-=x&-x) k+=f[x];return k;}
inline int ask(int k){
	int x=0;
	for (int i=m;i;i>>=1)
		if (x+i<=n&&k>=f[x+i]) x+=i,k-=f[x];
	return x+1;
}
inline void work(int x){
	int k=sum(x);add(x);
	a[i]+=k;if (a[i]>=i) a[i]-=i,a[i+1]++;
}
int main(){
	for (n=read(),i=1;i<=n;i++) v[i]=read()+1;
	for (i=1;i<=n;i++) work(v[n+1-i]);
	memset(f,0,sizeof(f));
	for (i=1;i<=n;i++) v[i]=read()+1;
	for (i=1;i<=n;i++) work(v[n+1-i]);
	for (m=1;m<=n;m<<=1);m>>=1;
	for (i=n;i;i--){
		int x=ask(a[i]);dec(x);
		write(x-1);putchar(' ');
	}
}


#include<cstdio>
#include<cstring>
const int N=2e5+5;
int n,m,i,v[N],f[N],a[N];
int read(){
	char c=getchar();int k=0;for (;c<48||c>57;c=getchar());
	for (;c>47&&c<58;c=getchar()) k=(k<<3)+(k<<1)+c-48;return k;
}
void write(int x){if (x>9) write(x/10);putchar(x%10+48);}
void add(int x){for (;x<=n;x+=x&-x) f[x]++;}
void dec(int x){for (;x<=n;x+=x&-x) f[x]--;}
int sum(int x){int k=0;for (;x;x-=x&-x) k+=f[x];return k;}
int ask(int k){
	int x=0;
	for (int i=m;i;i>>=1)
		if (x+i<=n&&k>=f[x+i]) x+=i,k-=f[x];
	return x+1;
}
void work(int x){
	int k=sum(x);add(x);
	a[i]+=k;if (a[i]>=i) a[i]-=i,a[i+1]++;
}
int main(){
	for (n=read(),i=1;i<=n;i++) v[i]=read()+1;
	for (i=1;i<=n;i++) work(v[n+1-i]);
	memset(f,0,sizeof(f));
	for (i=1;i<=n;i++) v[i]=read()+1;
	for (i=1;i<=n;i++) work(v[n+1-i]);
	for (m=1;m<=n;m<<=1);m>>=1;
	for (i=n;i;i--){
		int x=ask(a[i]);dec(x);
		write(x-1);putchar(' ');
	}
}


#include<iostream>
#include<time.h>
#include<math.h>
#include<limits.h>
#include<vector>
#include<map>
#include<stdio.h>
#include<cstdlib>
#include<string.h>
#define ini2(a,b,c); for(int i=0;i<a;i++)for(int j=0;j<b;j++)mem[i][j]=c;
#define ini1(a,c); for(int i=0;i<a;i++)mem[i]=c;
#define i(a) for(int i=0;i<a;i++)
#define j(a) for(int j=0;j<a;j++)
#define debug cout<<"here"<<endl;
#include<complex>
#include<algorithm>
#define Ceil(a,b) ((a+b-1)/b)
#define Round(a,b) ((a+b/2)/b)
// fabs(a-b)<=1e-8
using namespace std;
inline int d_compare(double x,double y){return (fabs(x-y)<=1e-8)?0:(x>y)?1:-1;}
//int dr[4]={0,0,-1,1},dc[4]={-1,1,0,0};
int successor;
class Node{
    public:
    int num,lsize,rsize,height;
    Node* left;Node* right;
    Node(int i)
    {
        num=i;lsize=rsize=height=1;
        left=right=NULL;
    }
    Node(int i,Node* l,Node* r)
    {
        num=i;left=l;right=r;
        update();
    }
    void update()
    {
        if(left==NULL&&right==NULL)
            lsize=rsize=height=1;
        else
        {
            if(left==NULL)
                lsize=1,rsize=right->lsize+right->rsize,height=1+right->height;
            else if(right==NULL)
                rsize=1,lsize=left->lsize+left->rsize,height=1+left->height;
            else
                lsize=left->lsize+left->rsize,rsize=right->lsize+right->rsize,height=1+max(left->height,right->height);
        }
    }
    int def()
    {
        if(left==NULL&&right==NULL)
            return 0;
        else if(left==NULL)
            return 0-right->height;
        else if(right==NULL)
            return left->height;
        else
        return left->height-right->height;
    }
    Node* rotate_r()
    {
        Node* hold=left;
        left=left->right;
        hold->right=this;
        update();
        hold->update();
        return hold;
    }
    Node* rotate_l()
    {
        Node* hold=right;
        right=right->left;
        hold->left=this;
        update();
        hold->update();
        return hold;
    }
    Node* balance()
    {
        Node* hold=this;
        if(def()==2)
        {
            if(left->def()==-1)
                left=left->rotate_l();
            hold=rotate_r();

        }
        else if(def()==-2)
        {
            if(right->def()==1)
                right=right->rotate_r();
            hold=rotate_l();
        }
        return hold;
    }
    Node* successor()
    {
        if(left==NULL)
            {::successor=num;Node* hold=right;delete this;return hold;}
        else
            left=left->successor();
        update();
        return balance();
    }
    Node* delete_Node(int e)
    {
        if(num==e)
        {
            if(left==NULL)
                {Node* hold=right;delete this;return hold;}
            else if(right==NULL)
                {Node* hold=left;delete this;return hold;}
            else
                {right=right->successor();num=::successor;}
        }
        else if(e<num)
            left=left->delete_Node(e);
        else
            right=right->delete_Node(e);
        update();
//        debug
        return balance();
    }
    int getvalue(int index)
    {
        index++;
        int i=0;Node* ptr=this;
        while(index!=i+ptr->lsize)
        {
            if(index<i+ptr->lsize)
                ptr=ptr->left;
            else
                i+=ptr->lsize,ptr=ptr->right;
        }
        return ptr->num;
    }
    int getindex(int e)
    {
        int i=0;Node* ptr=this;
        while(e!=ptr->num)
        {
            if(e<ptr->num)
                ptr=ptr->left;
            else
                i+=ptr->lsize,ptr=ptr->right;
        }
        return i+ptr->lsize-1;
    }
    Node* delete_index(int index,int i)
    {
        if(index==i+lsize)
        {
            if(left==NULL)
                {Node* hold=right;delete this;return hold;}
            else if(right==NULL)
                {Node* hold=left;delete this;return hold;}
            else
                {right=right->successor();num=::successor;}
        }
        else if(index<i+lsize)
            left=left->delete_index(index,i);
        else
            i+=lsize,right=right->delete_index(index,i);
        update();
//        debug
        return balance();
    }
};
Node* tree_fill(int* arr,int f,int l)
{

    if(f<=l)
    {
        int mid=(f+l)/2;
        Node* n=new Node(arr[mid]);
        n->left=tree_fill(arr,f,mid-1);
        n->right=tree_fill(arr,mid+1,l);
        n->update();
        return n;
    }
    else
        return NULL;
}
int main()
{
    int arr[200005],factoradic[200005];
    int n,temp,hold;
    cin>>n;
    i(n)
        arr[i]=i;
    Node* tree1=tree_fill(arr,0,n-1);Node* tree2=tree_fill(arr,0,n-1);Node* tree3=tree_fill(arr,0,n-1);

    i(n)
    {
        cin>>temp;
        hold=tree1->getindex(temp);
//        cout<<hold<<endl;
        factoradic[i]=hold;
        tree1=tree1->delete_Node(temp);
    }
    i(n)
    {
        cin>>temp;
        hold=tree2->getindex(temp);
//        cout<<hold<<endl;
        factoradic[i]+=hold;
        tree2=tree2->delete_Node(temp);
    }
    for(int i=n-1;i>0;i--)
    {
        if(factoradic[i]>n-i-1)
        {
            factoradic[i-1]+=factoradic[i]/(n-i);
            (factoradic[i]>=n-i)?factoradic[i]%=n-i:0;
        }
    }
    factoradic[0]%=n;
    i(n)
    {
        cout<<tree3->getvalue(factoradic[i])<<' ';
        tree3=tree3->delete_index(factoradic[i]+1,0);
    }
    cout<<endl;
    return 0;
}


#include<iostream>
#include<vector>
using namespace std;
int n;
int fac(unsigned int f)
{
    int fact=1;
    if( f > 1 )
        for(unsigned int k=2; k<=f; k++)
            fact = fact*k;
    return fact;
}
int get(vector<int>& bits,unsigned int num)
{
    int f=0,l=bits.size()-1;
    int mid=(f+l)/2;
    for(;f<=l;mid=(f+l)/2)
    {
        if(bits[mid]==num)
            {bits.erase(bits.begin() + mid);return mid;}
        else if(bits[mid]>num)
            l=mid-1;
        else if(bits[mid]<num)
            f=mid+1;
    }
    cout<<"Wrong in get"<<endl;
    return -1;
}

int main()
{
    int t=0,hold;
    cin>>n;
    vector<int> A(n);
    vector<int> B(n);
    vector<int> Abits(n);
    vector<int> Bbits(n);
    vector<int> Cbits(n);
    for(int i=0;i<n;i++)
        cin>>A[i];
    for(int i=0;i<n;i++)
        cin>>B[i];
    for(int i=0;i<n;i++)
        Abits[i]=Bbits[i]=Cbits[i]=i;
    for(int i=0;i<n-1;i++)
        t+=get(Abits,A[i])*fac(n-i-1);
    for(int i=0;i<n-1;i++)
        t+=get(Bbits,B[i])*fac(n-i-1);
    t%=fac(n);
    for(int i=0;;i++)
    {
        hold=fac(n-i-1);
        if(i==n-1)
        {
            cout<<Cbits[t/hold]<<endl;
            break;
        }
        cout<<Cbits[t/hold]<<" ";
        Cbits.erase(Cbits.begin()+ t/hold);
        t=t%hold;
    }
    return 0;
}


#include<iostream>
#include<time.h>
#include<math.h>
#include<limits.h>
#include<vector>
#include<map>
#include<stdio.h>
#include<cstdlib>
#include<string.h>
#define ini2(a,b,c); for(int i=0;i<a;i++)for(int j=0;j<b;j++)mem[i][j]=c;
#define ini1(a,c); for(int i=0;i<a;i++)mem[i]=c;
#define i(a) for(int i=0;i<a;i++)
#define j(a) for(int j=0;j<a;j++)
#define here cout<<"here"<<endl;
#include<complex>
#include<algorithm>
using namespace std;
#include<iostream>
#include<time.h>
#include<math.h>
#include<limits.h>
#include<vector>
#include<map>
#include<stdio.h>
#include<cstdlib>
#include<string.h>
#define ini2(a,b,c); for(int i=0;i<a;i++)for(int j=0;j<b;j++)mem[i][j]=c;
#define ini1(a,c); for(int i=0;i<a;i++)mem[i]=c;
#define i(a) for(int i=0;i<a;i++)
#define j(a) for(int j=0;j<a;j++)
#include<complex>
#include<algorithm>
using namespace std;
int bin(int val,vector<int>& arr)
{
    for(int m,f=0,l=(signed)arr.size();f<=l;)
    {
        m=(f+l)/2;
        if(arr[m]==val)
            return m;
        else if(arr[m]>val)
            l=m-1;
        else
            f=m+1;
    }
    return -1;
}
int main()
{
    ios_base::sync_with_stdio(false);
    int n;
    vector<int> arr1;
    cin>>n;
    arr1.resize(n);
    vector<int> factoradic(n);
    i(n)
        arr1[i]=i;
    vector<int> arr2(arr1),arr3(arr1);
    int num;
    i(n)
    {
        cin>>num;
        factoradic[i]=bin(num,arr1);
        arr1.erase(arr1.begin()+factoradic[i]);
    }
//    i(n)
//        cout<<factoradic[i]<<' ';
//    cout<<endl;
    i(n)
    {
        cin>>num;
        num=bin(num,arr2);
        factoradic[i]+=num;
        arr2.erase(arr2.begin()+num);
    }
//    i(n)
//        cout<<factoradic[i]<<' ';
//    cout<<endl;
    for(int i=n-1;i>0;i--)
    {
//        cout<<i<<"||"<<endl;
        if(factoradic[i]>n-i-1)
        {
            factoradic[i-1]+=factoradic[i]/(n-i);
            factoradic[i]%=n-i;
        }
//        i(n)
//            cout<<factoradic[i]<<' ';
//        cout<<endl;
    }
    factoradic[0]%=n;
//    i(n)
//        cout<<factoradic[i]<<' ';
//    cout<<endl;
    i(n)
    {
        cout<<arr3[factoradic[i]]<<' ';
        arr3.erase(arr3.begin()+factoradic[i]);
    }
    cout<<endl;
    return 0;
}


//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=200010;

int n;
int a[MAXN], b[MAXN];
int f[MAXN], c[MAXN];

void add(int x, int y)
{
    while (x <= n)
    {
        c[x] += y;
        x += lowbit(x);
    }
}

int sum(int x)
{
    int res = 0;
    while (x)
    {
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}

void init()
{
    CLR(c, 0);
    for (int i=1; i<=n; i++)
        add(i, 1);
}

int main()
{
    scand(n);
    for (int i=1; i<=n; i++)
    {
        read(a[i]);
        a[i]++;
    }
    for (int i=1; i<=n; i++)
    {
        read(b[i]);
        b[i]++;
    }
    init();
    for (int i=1; i<n; i++)
    {
        int les=sum(a[i]-1);
        f[n-i]+=les;
        add(a[i], -1);
    }
    init();
    for (int i=1; i<n; i++)
    {
        int les=sum(b[i]-1);
        f[n-i]+=les;
        add(b[i], -1);
    }
    for(int i=1; i<n; i++) //计算出逆序数
    {
        f[i+1]+=f[i]/(i+1);
        f[i]=f[i]%(i+1);
    }
    init();
    int sml=1;
    for (int i=n-1; i>=1; i--)
    {
        int l=1, r=n, mid, tmp, ans=-1;
        while (l <= r)
        {
            mid=MID(l,r);]
            tmp=sum(mid - 1);
            if(tmp <= f[i])
            {
                l=mid+1;
                ans=mid;
            }
            else
            {
                r=mid-1;
            }
        }
        if(ans == -1)
            ans=sml;
        printf("%d ", ans-1);
        add(ans, -1);
        while(!c[sml])
            sml++;
    }
    for(int i=1; i<=n; i++)
    {
        if(c[i])
        {
            printf("%d\n", i-1);
            break;
        }
    }
    return 0;
}


//      whn6325689
//		Mr.Phoebe
//		http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))
#define MID(x,y) (x+((y-x)>>1))
#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=200010;

int n;
int a[MAXN], b[MAXN];
int f[MAXN], c[MAXN];

void add(int x, int y)
{
    while (x <= n)
    {
        c[x] += y;
        x += lowbit(x);
    }
}

int sum(int x)
{
    int res = 0;
    while (x)
    {
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}

void init()
{
    CLR(c, 0);
    for (int i=1; i<=n; i++)
        add(i, 1);
}

int main()
{
    read(n);
    for (int i=1; i<=n; i++)
    {
        read(a[i]);
        a[i]++;
    }
    for (int i=1; i<=n; i++)
    {
        read(b[i]);
        b[i]++;
    }
    init();
    for (int i=1; i<n; i++)
    {
        int les=sum(a[i]-1);
        f[n-i]+=les;
        add(a[i], -1);
    }
    init();
    for (int i=1; i<n; i++)
    {
        int les=sum(b[i]-1);
        f[n-i]+=les;
        add(b[i], -1);
    }
    for(int i=1; i<n; i++) //计算出逆序数
    {
        f[i+1]+=f[i]/(i+1);
        f[i]=f[i]%(i+1);
    }
    init();
    int sml=1;
    for (int i=n-1; i>=1; i--)
    {
        int l=1, r=n, mid, tmp, ans=-1;
        while (l <= r)
        {
            mid=MID(l,r);
            tmp=sum(mid - 1);
            if(tmp <= f[i])
            {
                l=mid+1;
                ans=mid;
            }
            else
            {
                r=mid-1;
            }
        }
        if(ans == -1)
            ans=sml;
        printf("%d ", ans-1);
        add(ans, -1);
        while(!c[sml])
            sml++;
    }
    for(int i=1; i<=n; i++)
    {
        if(c[i])
        {
            printf("%d\n", i-1);
            break;
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct Node
{
int key,priority,size; // clave, prioridad (MaxHeap), tamaño del subarbol
Node* left, *right;
// puntero a subarbol izquierdo y derecho
Node(int k): key(k), left(NULL), right(NULL), priority(rand()), size(0) {}
};
int sz(Node* root) // Devuelve el tamaño del subarbol de un nodo
{
return (root == NULL)? 0 : root->size;
}
Node* upd(Node* root) // Actualiza el tamaño del subarbol de un nodo
{
if(root != NULL) root->size = 1 + sz(root->left) + sz(root->right);
return root;
}
// Busqueda de un nodo por su clave, cumple propiedades de BST
Node* search(Node *root , int key)
{
if(root == NULL) return NULL;
if(key < root->key) return search(root->left, key);
if(key > root->key) return search(root->right, key);
return root;
}
// Rotacion a la Derecha
Node* rotRight(Node *root)
{
Node* pivot = root->left; // Asigno a pivot el subarbol izquierdo de root
root->left = pivot->right; // Puntero izq de root apunta a der de pivot
pivot->right = root;
// Puntero derecho de pivot apunta a root
return pivot;
}
//Rotacion a la Izquierda
Node* rotLeft(Node *root)
{
Node* pivot = root->right; // Asigno a pivot el subarbol derecho de root
root->right = pivot->left; // Puntero der de root apunta a izq de pivot
pivot->left = root;
// Puntero izquierdo de pivot apunta a root
return pivot;
}
// Insercion: Recibo un arbol y el nodo a insertar
Node* insert(Node *root , Node *novo)
{
if(root == NULL) return upd(novo); // Encontre la posicion para el nodo
if(root->key < novo->key)
// Buscamos por la derecha
{
root->right = insert(root->right, novo);
if(root->right->priority > root->priority) root = rotLeft(root); // rotLeft
upd(root->left);
}
else
// Buscamos por la izquierda
{
root->left = insert(root->left, novo);
if(root->left->priority > root->priority)root = rotRight(root); // rotRight
upd(root->right);
}
return upd(root);
}
//Eliminacion: Recibo un arbol y la clave del nodo a eliminar
Node* erase(Node* root, int key)
{
if(root == NULL) return upd(root);
//Realizo la busqueda por clave
if(root->key < key) root->right = erase(root->right, key);
else if(root->key > key) root->left = erase(root->left, key);
else
{
// Si tengo ambos hijos debo comparar prioridades
if(root->left != NULL)
{
if(root->right != NULL){ // Elijo el de mayor prioridad
if(root->left->priority < root->right->priority){
root = rotLeft(root); // rotacion izquierda
upd(root->left);
root->left = erase(root->left, key);
}else{
root = rotRight(root); // rotacion derecha
upd(root->right);
root->right = erase(root->right, key);
}
}else{
// Si tengo solo hijo izquierdo
Node* aux = root->left; delete root; return upd(aux);
}
}
else{
if(root->right != NULL){ // Si tengo solo hijo derecho
Node* aux = root->right; delete root; return upd(aux);
}
else{ // Si mi nodo actual es hoja lo elimino
delete root; return NULL;
}
}
}
return upd(root);
}
//Limpiamos el arbol de prueba
void clear(Node* root)
{
if(root != NULL)
{
clear(root->left); clear(root->right);
delete root;
}
}
// Recorrido Preorder del Treap
void Traverse(Node *root)
{
if(root == NULL) return;
printf("[%d,%d,%d]->", root->key, root->priority, sz(root));
Traverse(root->left);
Traverse(root->right);
}
Node* find_kth(Node *root, int k)
{
if(sz(root) < k) return NULL; // Si no poseo elementos retorno NULL
int ans = 1 + sz(root->left); // La posición del nodo es 1 + tam hijo izq
if(ans == k) return root;
// Si es el nodo actual lo retorno
// Si esta en el subarbol derecho, busco el (k - ans) menor elemento
if(ans < k) return find_kth(root->right, k - ans);
// Si esta en el subarbol izquierdo, sigo buscando
return find_kth(root->left, k);
}
int count(Node *root, int d) // Cuenta los elementos menores a d
{
if(root == NULL) return 0;
if(root->key < d) return 1 + sz(root->left) + count(root->right, d);
else return count(root->left, d);
}
int main(){
    int n;
    cin>>n;
    string str;
    vector<int> a(n);
    vector<int> b(n);
    for(int i=0;i<n;++i)
        cin>>a[i];
    for(int i=0;i<n;++i)
        cin>>b[i];
    vector<int> ca(n);
    vector<int> cb(n);
    Node* ta= NULL;
    Node* tb= NULL;
    for(int i=0;i<n;++i) ta=insert(ta, new Node(i));
    for(int i=0;i<n;++i){
        ca[n-1-i]=count(ta,a[i]);
        ta=erase(ta,a[i]);
    }
    for(int i=0;i<n;++i) tb=insert(tb, new Node(i));
    for(int i=0;i<n;++i){
        cb[n-1-i]=count(tb,b[i]);
        tb=erase(tb,b[i]);
    }
    int carry=0;
    vector<int> ord(n);
    for(int i=0;i<n;++i){
        int num=ca[i]+cb[i]+carry;
        if(num>i) {
            carry= 1;
            num-=i+1;
        }else carry=0;
        ord[i]=num;
        cout<<ord[i]<<endl;
    }
    Node* tmp= NULL;
    Node* ans= NULL;
    for(int i=0;i<n;++i) tmp=insert(tmp, new Node(i));
    for(int i=n-1;i>=0;--i){
        int kth=find_kth(tmp,ord[i]+1)->key;
        cout<<kth<<" ";
        tmp=erase(tmp,kth);
    }
}


#include <bits/stdc++.h>
using namespace std;
struct Node
{
int key,priority,size; // clave, prioridad (MaxHeap), tamaño del subarbol
Node* left, *right;
// puntero a subarbol izquierdo y derecho
Node(int k): key(k), left(NULL), right(NULL), priority(rand()), size(0) {}
};
int sz(Node* root) // Devuelve el tamaño del subarbol de un nodo
{
return (root == NULL)? 0 : root->size;
}
Node* upd(Node* root) // Actualiza el tamaño del subarbol de un nodo
{
if(root != NULL) root->size = 1 + sz(root->left) + sz(root->right);
return root;
}
// Busqueda de un nodo por su clave, cumple propiedades de BST
Node* search(Node *root , int key)
{
if(root == NULL) return NULL;
if(key < root->key) return search(root->left, key);
if(key > root->key) return search(root->right, key);
return root;
}
// Rotacion a la Derecha
Node* rotRight(Node *root)
{
Node* pivot = root->left; // Asigno a pivot el subarbol izquierdo de root
root->left = pivot->right; // Puntero izq de root apunta a der de pivot
pivot->right = root;
// Puntero derecho de pivot apunta a root
return pivot;
}
//Rotacion a la Izquierda
Node* rotLeft(Node *root)
{
Node* pivot = root->right; // Asigno a pivot el subarbol derecho de root
root->right = pivot->left; // Puntero der de root apunta a izq de pivot
pivot->left = root;
// Puntero izquierdo de pivot apunta a root
return pivot;
}
// Insercion: Recibo un arbol y el nodo a insertar
Node* insert(Node *root , Node *novo)
{
if(root == NULL) return upd(novo); // Encontre la posicion para el nodo
if(root->key < novo->key)
// Buscamos por la derecha
{
root->right = insert(root->right, novo);
if(root->right->priority > root->priority) root = rotLeft(root); // rotLeft
upd(root->left);
}
else
// Buscamos por la izquierda
{
root->left = insert(root->left, novo);
if(root->left->priority > root->priority)root = rotRight(root); // rotRight
upd(root->right);
}
return upd(root);
}
//Eliminacion: Recibo un arbol y la clave del nodo a eliminar
Node* erase(Node* root, int key)
{
if(root == NULL) return upd(root);
//Realizo la busqueda por clave
if(root->key < key) root->right = erase(root->right, key);
else if(root->key > key) root->left = erase(root->left, key);
else
{
// Si tengo ambos hijos debo comparar prioridades
if(root->left != NULL)
{
if(root->right != NULL){ // Elijo el de mayor prioridad
if(root->left->priority < root->right->priority){
root = rotLeft(root); // rotacion izquierda
upd(root->left);
root->left = erase(root->left, key);
}else{
root = rotRight(root); // rotacion derecha
upd(root->right);
root->right = erase(root->right, key);
}
}else{
// Si tengo solo hijo izquierdo
Node* aux = root->left; delete root; return upd(aux);
}
}
else{
if(root->right != NULL){ // Si tengo solo hijo derecho
Node* aux = root->right; delete root; return upd(aux);
}
else{ // Si mi nodo actual es hoja lo elimino
delete root; return NULL;
}
}
}
return upd(root);
}
//Limpiamos el arbol de prueba
void clear(Node* root)
{
if(root != NULL)
{
clear(root->left); clear(root->right);
delete root;
}
}
// Recorrido Preorder del Treap
void Traverse(Node *root)
{
if(root == NULL) return;
printf("[%d,%d,%d]->", root->key, root->priority, sz(root));
Traverse(root->left);
Traverse(root->right);
}
Node* find_kth(Node *root, int k)
{
if(sz(root) < k) return NULL; // Si no poseo elementos retorno NULL
int ans = 1 + sz(root->left); // La posición del nodo es 1 + tam hijo izq
if(ans == k) return root;
// Si es el nodo actual lo retorno
// Si esta en el subarbol derecho, busco el (k - ans) menor elemento
if(ans < k) return find_kth(root->right, k - ans);
// Si esta en el subarbol izquierdo, sigo buscando
return find_kth(root->left, k);
}
int count(Node *root, int d) // Cuenta los elementos menores a d
{
if(root == NULL) return 0;
if(root->key < d) return 1 + sz(root->left) + count(root->right, d);
else return count(root->left, d);
}
int main(){
    int n;
    cin>>n;
    string str;
    vector<int> a(n);
    vector<int> b(n);
    for(int i=0;i<n;++i)
        cin>>a[i];
    for(int i=0;i<n;++i)
        cin>>b[i];
    vector<int> ca(n);
    vector<int> cb(n);
    Node* ta= NULL;
    Node* tb= NULL;
    for(int i=0;i<n;++i) ta=insert(ta, new Node(i));
    for(int i=0;i<n;++i){
        ca[n-1-i]=count(ta,a[i]);
        ta=erase(ta,a[i]);
    }
    for(int i=0;i<n;++i) tb=insert(tb, new Node(i));
    for(int i=0;i<n;++i){
        cb[n-1-i]=count(tb,b[i]);
        tb=erase(tb,b[i]);
    }
    int carry=0;
    vector<int> ord(n);
    for(int i=0;i<n;++i){
    	int num=ca[i]+cb[i]+carry;
    	if(num>i) {
    		carry= 1;
    		num-=i+1;
    	}
    	ord[i]=num;
    }
    Node* tmp= NULL;
    Node* ans= NULL;
    for(int i=0;i<n;++i) tmp=insert(tmp, new Node(i));
    for(int i=n-1;i>=0;--i){
    	int kth=find_kth(tmp,ord[i]+1)->key;
    	cout<<kth<<" ";
    	tmp=erase(tmp,ord[i]);
    }
}


#include <bits/stdc++.h>
using namespace std;
struct Node
{
int key,priority,size; // clave, prioridad (MaxHeap), tamaño del subarbol
Node* left, *right;
// puntero a subarbol izquierdo y derecho
Node(int k): key(k), left(NULL), right(NULL), priority(rand()), size(0) {}
};
int sz(Node* root) // Devuelve el tamaño del subarbol de un nodo
{
return (root == NULL)? 0 : root->size;
}
Node* upd(Node* root) // Actualiza el tamaño del subarbol de un nodo
{
if(root != NULL) root->size = 1 + sz(root->left) + sz(root->right);
return root;
}
// Busqueda de un nodo por su clave, cumple propiedades de BST
Node* search(Node *root , int key)
{
if(root == NULL) return NULL;
if(key < root->key) return search(root->left, key);
if(key > root->key) return search(root->right, key);
return root;
}
// Rotacion a la Derecha
Node* rotRight(Node *root)
{
Node* pivot = root->left; // Asigno a pivot el subarbol izquierdo de root
root->left = pivot->right; // Puntero izq de root apunta a der de pivot
pivot->right = root;
// Puntero derecho de pivot apunta a root
return pivot;
}
//Rotacion a la Izquierda
Node* rotLeft(Node *root)
{
Node* pivot = root->right; // Asigno a pivot el subarbol derecho de root
root->right = pivot->left; // Puntero der de root apunta a izq de pivot
pivot->left = root;
// Puntero izquierdo de pivot apunta a root
return pivot;
}
// Insercion: Recibo un arbol y el nodo a insertar
Node* insert(Node *root , Node *novo)
{
if(root == NULL) return upd(novo); // Encontre la posicion para el nodo
if(root->key < novo->key)
// Buscamos por la derecha
{
root->right = insert(root->right, novo);
if(root->right->priority > root->priority) root = rotLeft(root); // rotLeft
upd(root->left);
}
else
// Buscamos por la izquierda
{
root->left = insert(root->left, novo);
if(root->left->priority > root->priority)root = rotRight(root); // rotRight
upd(root->right);
}
return upd(root);
}
//Eliminacion: Recibo un arbol y la clave del nodo a eliminar
Node* erase(Node* root, int key)
{
if(root == NULL) return upd(root);
//Realizo la busqueda por clave
if(root->key < key) root->right = erase(root->right, key);
else if(root->key > key) root->left = erase(root->left, key);
else
{
// Si tengo ambos hijos debo comparar prioridades
if(root->left != NULL)
{
if(root->right != NULL){ // Elijo el de mayor prioridad
if(root->left->priority < root->right->priority){
root = rotLeft(root); // rotacion izquierda
upd(root->left);
root->left = erase(root->left, key);
}else{
root = rotRight(root); // rotacion derecha
upd(root->right);
root->right = erase(root->right, key);
}
}else{
// Si tengo solo hijo izquierdo
Node* aux = root->left; delete root; return upd(aux);
}
}
else{
if(root->right != NULL){ // Si tengo solo hijo derecho
Node* aux = root->right; delete root; return upd(aux);
}
else{ // Si mi nodo actual es hoja lo elimino
delete root; return NULL;
}
}
}
return upd(root);
}
//Limpiamos el arbol de prueba
void clear(Node* root)
{
if(root != NULL)
{
clear(root->left); clear(root->right);
delete root;
}
}
// Recorrido Preorder del Treap
void Traverse(Node *root)
{
if(root == NULL) return;
printf("[%d,%d,%d]->", root->key, root->priority, sz(root));
Traverse(root->left);
Traverse(root->right);
}
Node* find_kth(Node *root, int k)
{
if(sz(root) < k) return NULL; // Si no poseo elementos retorno NULL
int ans = 1 + sz(root->left); // La posición del nodo es 1 + tam hijo izq
if(ans == k) return root;
// Si es el nodo actual lo retorno
// Si esta en el subarbol derecho, busco el (k - ans) menor elemento
if(ans < k) return find_kth(root->right, k - ans);
// Si esta en el subarbol izquierdo, sigo buscando
return find_kth(root->left, k);
}
int count(Node *root, int d) // Cuenta los elementos menores a d
{
if(root == NULL) return 0;
if(root->key < d) return 1 + sz(root->left) + count(root->right, d);
else return count(root->left, d);
}
int main(){
    int n;
    cin>>n;
    string str;
    vector<int> a(n);
    vector<int> b(n);
    for(int i=0;i<n;++i)
        cin>>a[i];
    for(int i=0;i<n;++i)
        cin>>b[i];
    vector<int> ca(n);
    vector<int> cb(n);
    Node* ta= NULL;
    Node* tb= NULL;
    for(int i=0;i<n;++i) ta=insert(ta, new Node(i));
    for(int i=0;i<n;++i){
        ca[n-1-i]=count(ta,a[i]);
        ta=erase(ta,a[i]);
    }
    for(int i=0;i<n;++i) tb=insert(tb, new Node(i));
    for(int i=0;i<n;++i){
        cb[n-1-i]=count(tb,b[i]);
        tb=erase(tb,b[i]);
    }
    int carry=0;
    vector<int> ord(n);
    for(int i=0;i<n;++i){
        int num=ca[i]+cb[i]+carry;
        if(num>i) {
            carry= 1;
            num-=i+1;
        }else carry=0;
        ord[i]=num;
    }
    Node* tmp= NULL;
    Node* ans= NULL;
    for(int i=0;i<n;++i) tmp=insert(tmp, new Node(i));
    for(int i=n-1;i>=0;--i){
        int kth=find_kth(tmp,ord[i]+1)->key;
        cout<<kth<<" ";
        tmp=erase(tmp,kth);
    }
}


#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> II;
typedef vector< II > VII;
typedef vector<int> VI;
typedef vector< VI > VVI;
typedef long long int ll;

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define ALL(a) a.begin(),a.end()
#define SET(a,b) memset(a,b,sizeof(a))

#define si(n) scanf("%d",&n)
#define dout(n) printf("%d\n",n)
#define sll(n) scanf("%lld",&n)
#define lldout(n) printf("%lld\n",n)
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL)

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__,__VA_ARGS__)
/*template <typename Arg1>
void __f(const char * name, Arg1&& arg1){
    cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1,',');cerr.write(names,comma - names) << " : " << arg1<<" | ";__f(comma+1,args...);
}*/
#else
#define trace(...)
#endif

ll tree[900010],p[200050],q[200010],op[200010],oq[200010],n,oans[200010],ans[200010];

void update(ll ind,ll val)
{
  while(ind<=n)
  {
    tree[ind]+=val;
    ind+=(ind & -ind);
  }
}

ll query(ll ind)
{
  ll sum=0;
  while(ind>0)
  {
    sum+=tree[ind];
    ind-=(ind & -ind);
  }
  return sum;
}

void buildsegtree(ll ti,ll l,ll r)
{
  if(l==r)
  {
    tree[ti]=op[l];
    return ;
  }
  ll m=(l+r)/2;
  buildsegtree(2*ti,l,m);
  buildsegtree(2*ti+1,m+1,r);
  tree[ti] = tree[2*ti] + tree[2*ti+1];
}

ll query(ll ti,ll l,ll r,ll req)
{
  ll m=(l+r)/2;
  if(l==r)
  {
    return l;
  }
  else if(tree[2*ti]<=req)
  {
    return query(2*ti+1,m+1,r,req-tree[2*ti]);
  }
  else if(tree[2*ti]>req)
  {
    return query(2*ti,l,m,req);
  }
}

void updatetree(ll ti,ll l,ll r,ll pos,ll val)
{
  if(pos<l || pos>r)
  {
    return ;
  }
  if(l==r && pos==l)
  {
    tree[ti]=val;
    return;
  }
  ll m=(l+r)/2;
  updatetree(2*ti,l,m,pos,val);
  updatetree(2*ti+1,m+1,r,pos,val);
  tree[ti]=tree[2*ti]+tree[2*ti+1];
}

int main()
{
  ll i;
  sll(n);
  SET(tree,0);
  for(i=1;i<=n;i++)
  {
    sll(p[i]);
    update(i,1);
  }
  for(i=1;i<=n;i++)
  {
    op[i]=query(p[i]);
    update(p[i]+1,-1);
    //cout << op[i] << endl;
  }
  SET(tree,0);
  for(i=1;i<=n;i++)
  {
    sll(q[i]);
    update(i,1);
  }
  for(i=1;i<=n;i++)
  {
    oq[i]=query(q[i]);
    update(q[i]+1,-1);
  }
  oans[n]=(op[n]+oq[n])%1;
  for(i=1;i<n;i++)
  {
    oans[n-i]=((op[n-i]+oq[n-i]) + (op[n-i+1]+oq[n-i+1])/i )%(i+1);
  }
  /*for(i=1;i<=n;i++)
  {
    cout << oans[i] << " ";
  }
  cout << endl;*/
  for(i=0;i<n;i++)
  {
    op[i]=1;
  }
  buildsegtree(1,0,n-1);
  for(i=1;i<=n;i++)
  {
    ans[i]=query(1,0,n-1,oans[i]);
    updatetree(1,0,n-1,ans[i],0);
  }
  for(i=1;i<=n;i++)
  {
    cout << ans[i] << " ";
  }
  cout << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> II;
typedef vector< II > VII;
typedef vector<int> VI;
typedef vector< VI > VVI;
typedef long long int ll;

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(a) (int)(a.size())
#define ALL(a) a.begin(),a.end()
#define SET(a,b) memset(a,b,sizeof(a))

#define si(n) scanf("%d",&n)
#define dout(n) printf("%d\n",n)
#define sll(n) scanf("%lld",&n)
#define lldout(n) printf("%lld\n",n)
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL)

#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__,__VA_ARGS__)
/*template <typename Arg1>
void __f(const char * name, Arg1&& arg1){
    cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1,',');cerr.write(names,comma - names) << " : " << arg1<<" | ";__f(comma+1,args...);
}*/
#else
#define trace(...)
#endif

ll tree[900010],p[900050],q[900010],op[900010],oq[900010],n,oans[900010],ans[900010],sum[200010];

void update(ll ind,ll val)
{
  while(ind<=n)
  {
    tree[ind]+=val;
    ind+=(ind & -ind);
  }
}

ll query(ll ind)
{
  ll sum=0;
  while(ind>0)
  {
    sum+=tree[ind];
    ind-=(ind & -ind);
  }
  return sum;
}

void buildsegtree(ll ti,ll l,ll r)
{
  if(l==r)
  {
    tree[ti]=op[l];
    return ;
  }
  ll m=(l+r)/2;
  buildsegtree(2*ti,l,m);
  buildsegtree(2*ti+1,m+1,r);
  tree[ti] = tree[2*ti] + tree[2*ti+1];
}

ll query(ll ti,ll l,ll r,ll req)
{
  ll m=(l+r)/2;
  if(l==r)
  {
    return l;
  }
  else if(tree[2*ti]<=req)
  {
    return query(2*ti+1,m+1,r,req-tree[2*ti]);
  }
  else if(tree[2*ti]>req)
  {
    return query(2*ti,l,m,req);
  }
}

void updatetree(ll ti,ll l,ll r,ll pos,ll val)
{
  if(pos<l || pos>r)
  {
    return ;
  }
  if(l==r && pos==l)
  {
    tree[ti]=val;
    return;
  }
  ll m=(l+r)/2;
  updatetree(2*ti,l,m,pos,val);
  updatetree(2*ti+1,m+1,r,pos,val);
  tree[ti]=tree[2*ti]+tree[2*ti+1];
}

int main()
{
  ll i;
  sll(n);
  SET(tree,0);
  for(i=1;i<=n;i++)
  {
    sll(p[i]);
    update(i,1);
  }
  for(i=1;i<=n;i++)
  {
    op[i]=query(p[i]);
    update(p[i]+1,-1);
  //  cout << op[i] << " ";
  }
//  cout << endl;
  SET(tree,0);
  for(i=1;i<=n;i++)
  {
    sll(q[i]);
    update(i,1);
  }
  for(i=1;i<=n;i++)
  {
    oq[i]=query(q[i]);
    update(q[i]+1,-1);
  //  cout << oq[i] << " ";
  }
  SET(sum,0);
//  cout << endl;
  oans[n]=(op[n]+oq[n])%1;
  sum[n]=op[n]+oq[n];
  for(i=1;i<=n;i++)
  {
    sum[i]=op[i]+oq[i];
  }
  for(i=n-1;i>=1;i--)
  {
    sum[i-1]=sum[i-1]+sum[i]/(n-i+1);
    //sum[i]=(sum[i]+sum[i+1]/(n-i+1));
  //  sum[i+1]=sum[i+1]%(n-i+1);
  sum[i]=sum[i]%(n-i+1);
    //  printf("%d %d %d\n",sum[i],sum[i+1],i);
  }
//  sum[1]=sum[1]%n;
  for(i=1;i<n;i++)
  {
    oans[i]=((op[i]+oq[i]) + (op[i+1]+oq[i+1])/(n-i) )%(n-i+1);
  }
/*  for(i=1;i<=n;i++)
  {
    cout << sum[i] << "  ";
  }*/
  //cout << endl;
  for(i=0;i<n;i++)
  {
    op[i]=1;
  }
  buildsegtree(1,0,n-1);
  for(i=1;i<=n;i++)
  {
    ans[i]=query(1,0,n-1,sum[i]);
    updatetree(1,0,n-1,ans[i],0);
  }
  for(i=1;i<=n;i++)
  {
    cout << ans[i] << " ";
  }
  cout << endl;
  return 0;
}


#include<iostream>
using namespace std;

int aib[3][200003];

int prev(int i){
    return i & (i-1);
}

int next(int i){
    return  (i << 1) - (i & (i-1) );
}

int sum(int t,int i){
    int sol = 0;
    while (i>0){
        sol += aib[t][i];
        i = prev(i);
    }

    return sol;
}

int n,t;

void update(int t,int i){
    while (i < n+1){
        aib[t][i]++;
        i = next(i);
    }
}

int sir[2][200002], useful[2][200002];
int useSol[200002], sol[200002];

int query(int k){

    int r=n,l=n,mid;
    int sol = sum(2,n), s;
    while ((l-1-sol) >= k){
        sol -= aib[2][l];
        r = l;
        l = prev(l);

    }

    while (r-l > 1){
        mid = (r+l) / 2;
        s = aib[2][mid];
        if (mid - 1 - sol - s <= k) {l = mid; sol += s;}
        else r = mid;
    }
    if (l-1-sol == k) return l;
    else return r;
}

int main(void){
    cin >> n;
    int i;

    for(t=0;t<=1;t++){
        for(i=1;i<=n;i++){
            cin >> sir[t][i];
            useful[t][i] = sir[t][i] - sum( t, sir[t][i]+1 );
            update(t,sir[t][i]+1);
        }
    }

    int carry = 0;
    for(i=n;i>=1;i--){
        if (useful[0][i] + useful[1][i] + carry>= (n-i+1)){
            useSol[i] = (useful[0][i] + useful[1][i] + carry) - (n-i+1);
            carry = 1;
        }
        else{
            useSol[i] = useful[0][i] + useful[1][i] + carry;
            carry = 0;
        }
    }
    for(i=1;i<=n;i++){
        sol[i] = query(useSol[i]) - 1;
        update(2,sol[i] + 1);
        cout << sol[i] << " ";
    }

}


#include<iostream>
using namespace std;

int aib[3][200003];

int prev(int i){
    return i & (i-1);
}

int next(int i){
    return  (i << 1) - (i & (i-1) );
}

int sum(int t,int i){
    int sol = 0;
    while (i>0){
        sol += aib[t][i];
        i = prev(i);
    }

    return sol;
}

int n,t;

void update(int t,int i){
    while (i < n+1){
        aib[t][i]++;
        i = next(i);
    }
}

int sir[2][200002], useful[2][200002];
int useSol[200002], sol[200002];

int query(int k){

    int r=n,l=n,mid;
    int sol = sum(2,n), s;
    while ((l-1-sol) >= k){
        sol -= aib[2][l];
        r = l;
        l = prev(l);

    }

    while (r-l > 1){
        mid = (r+l) / 2;
        s = aib[2][mid];
        if (mid - 1 - sol - s >= k) r = mid;
        else {l = mid; sol += s;}
    }

    if (l-1-sol == k) return l;
    else return r;
}

int main(void){
    cin >> n;
    int i;

    for(t=0;t<=1;t++){
        for(i=1;i<=n;i++){
            cin >> sir[t][i];
            useful[t][i] = sir[t][i] - sum( t, sir[t][i]+1 );
            update(t,sir[t][i]+1);
        }
    }

    int carry = 0;
    for(i=n;i>=1;i--){
        if (useful[0][i] + useful[1][i] + carry>= (n-i+1)){
            useSol[i] = (useful[0][i] + useful[1][i] + carry) - (n-i+1);
            carry = 1;
        }
        else{
            useSol[i] = useful[0][i] + useful[1][i] + carry;
            carry = 0;
        }
    }
    for(i=1;i<=n;i++){
        sol[i] = query(useSol[i]) - 1;
        update(2,sol[i] + 1);
        cout << sol[i] << " ";
    }

}


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1000005;
int n,A[N],B[N],C[N],v[N<<2];
void modify(int pos,int l,int r,int x,int val)
{
	if (l==r)
		{ v[pos]=val; return; }
	int mid=l+r>>1;
	if (x<=mid)
		modify(pos<<1,l,mid,x,val);
	else
		modify(pos<<1|1,mid+1,r,x,val);
	v[pos]=v[pos<<1]+v[pos<<1|1];
}
int ask(int pos,int l,int r,int x)
{
	if (l==r)
		return 0;
	int mid=l+r>>1;
	if (x<=mid)
		return ask(pos<<1,l,mid,x);
	else
		return v[pos<<1]+ask(pos<<1|1,mid+1,r,x);
}
int query(int pos,int l,int r,int rk)
{
	int mid=l+r>>1;
	if (l==r) return l;
	if (v[pos<<1]>=rk)
		return query(pos<<1,l,mid,rk);
	else
		return query(pos<<1|1,mid+1,r,rk-v[pos<<1]);
}
int main()
{
	//freopen("permu.in","r",stdin);
	//freopen("permu.out","w",stdout);
	scanf("%d",&n);
	for(int i=n;i>=1;i--)
		scanf("%d",&A[i]);
	for(int i=n;i>=1;i--)
		scanf("%d",&B[i]);
	for(int i=n;i>=1;i--)
		modify(1,0,n-1,A[i],1);
	for(int i=n;i>=1;i--)
	{
		modify(1,0,n-1,A[i],0);
		A[i]=ask(1,0,n-1,A[i]);
	}
	for(int i=n;i>=1;i--)
		modify(1,0,n-1,B[i],1);
	for(int i=n;i>=1;i--)
	{
		modify(1,0,n-1,B[i],0);
		B[i]=ask(1,0,n-1,B[i]);
	}
	for(int i=1;i<=n;i++)
	{
		C[i]+=A[i]+B[i];
		C[i+1]+=C[i]/i,C[i]%=i;
	}
	for(int i=1;i<=n;i++)
		modify(1,0,n-1,i-1,1);
	for(int Ans,i=n;i>=1;i--)
	{
		Ans=query(1,0,n-1,C[i]+1);
		printf("%d ",Ans);
		modify(1,0,n-1,Ans,0);
	}

	return 0;
}
/*
5
2 1 3 0 4
2 0 4 3 1
*/


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1000005;
int n,A[N],B[N],C[N],v[N<<2];
void modify(int pos,int l,int r,int x,int val)
{
	if (l==r)
		{ v[pos]=val; return; }
	int mid=l+r>>1;
	if (x<=mid)
		modify(pos<<1,l,mid,x,val);
	else
		modify(pos<<1|1,mid+1,r,x,val);
	v[pos]=v[pos<<1]+v[pos<<1|1];
}
int ask(int pos,int l,int r,int x)
{
	if (l==r)
		return 0;
	int mid=l+r>>1;
	if (x<=mid)
		return ask(pos<<1,l,mid,x);
	else
		return v[pos<<1]+ask(pos<<1|1,mid+1,r,x);
}
int query(int pos,int l,int r,int rk)
{
	int mid=l+r>>1;
	if (l==r) return l;
	if (v[pos<<1]>=rk)
		return query(pos<<1,l,mid,rk);
	else
		return query(pos<<1,mid+1,r,rk-v[pos<<1]);
}
int main()
{
	scanf("%d",&n);
	for(int i=n;i>=1;i--)
		scanf("%d",&A[i]);
	for(int i=n;i>=1;i--)
		scanf("%d",&B[i]);
	for(int i=n;i>=1;i--)
		modify(1,0,n-1,A[i],1);
	for(int i=n;i>=1;i--)
	{
		A[i]=ask(1,0,n-1,A[i]);
		modify(1,0,n-1,A[i],0);
	}
	for(int i=n;i>=1;i--)
		modify(1,0,n-1,B[i],1);
	for(int i=n;i>=1;i--)
	{
		B[i]=ask(1,0,n-1,B[i]);
		modify(1,0,n-1,B[i],0);
	}
	for(int i=1;i<=n;i++)
	{
		C[i]+=A[i]+B[i];
		C[i+1]+=C[i]/i,C[i]%=i;
	}
	for(int i=1;i<=n;i++)
		modify(1,0,n-1,i-1,1);
	for(int i=n;i>=1;i--)
	{
		int Ans=query(1,0,n-1,C[i]+1);
		printf("%d ",Ans);
		modify(1,0,n-1,Ans,0);
	}

	return 0;
}
/*
3
1 2 0
2 1 0
*/


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1000005;
int n,A[N],B[N],C[N],v[N<<2];
void modify(int pos,int l,int r,int x,int val)
{
	if (l==r)
		{ v[pos]=val; return; }
	int mid=l+r>>1;
	if (x<=mid)
		modify(pos<<1,l,mid,x,val);
	else
		modify(pos<<1|1,mid+1,r,x,val);
	v[pos]=v[pos<<1]+v[pos<<1|1];
}
int ask(int pos,int l,int r,int x)
{
	if (l==r)
		return 0;
	int mid=l+r>>1;
	if (x<=mid)
		return ask(pos<<1,l,mid,x);
	else
		return v[pos<<1]+ask(pos<<1|1,mid+1,r,x);
}
int query(int pos,int l,int r,int rk)
{
	int mid=l+r>>1;
	if (l==r) return l;
	if (v[pos<<1]>=rk)
		return query(pos<<1,l,mid,rk);
	else
		return query(pos<<1,mid+1,r,rk-v[pos<<1]);
}
int main()
{
	//freopen("permu.in","r",stdin);
	//freopen("permu.out","w",stdout);
	scanf("%d",&n);
	for(int i=n;i>=1;i--)
		scanf("%d",&A[i]);
	for(int i=n;i>=1;i--)
		scanf("%d",&B[i]);
	for(int i=n;i>=1;i--)
		modify(1,0,n-1,A[i],1);
	for(int i=n;i>=1;i--)
	{
		modify(1,0,n-1,A[i],0);
		A[i]=ask(1,0,n-1,A[i]);
	}
	for(int i=n;i>=1;i--)
		modify(1,0,n-1,B[i],1);
	for(int i=n;i>=1;i--)
	{
		modify(1,0,n-1,B[i],0);
		B[i]=ask(1,0,n-1,B[i]);
	}
	for(int i=1;i<=n;i++)
	{
		C[i]+=A[i]+B[i];
		C[i+1]+=C[i]/i,C[i]%=i;
	}
	for(int i=1;i<=n;i++)
		modify(1,0,n-1,i-1,1);
	for(int Ans,i=n;i>=1;i--)
	{
		Ans=query(1,0,n-1,C[i]+1);
		printf("%d ",Ans);
		modify(1,0,n-1,Ans,0);
	}

	return 0;
}
/*
5
2 1 3 0 4
2 0 4 3 1
*/


#include <bits/stdc++.h>

using namespace std;

#define rep(i, t) for(ll (i) = 0; (i) < (ll)(t); (i)++)
#define reu(i, s, e) for(ll (i) = (ll)(s); (i) <= (ll)(e); (i)++)
#define rer(i, s, e) for(ll (i) = (ll)(s); (i) < (ll)(e); (i)++)
#define For(i, v) for(__typeof((v).begin()) (i) = (v).begin(); (i) != (v).end(); (i) ++)
#define mset(arr, val) memset(arr, (val), sizeof arr)
#define PB push_back
#define MP make_pair
#define p1 first
#define p2 second

typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<int, int> pie;

const int maxn = 2e5 + 10;
int af[maxn], bf[maxn], sf[maxn];
int Ta[2 * maxn], Tb[2 * maxn], Ts[2 * maxn];
int s[maxn];

int F(int *T, int L, int R, int id, int idx){
	T[id] ++;
	if(R - L == 1)
		return 0;
	int mid = (L + R) >> 1;
	if(idx < mid)
		return F(T, L, mid, id * 2, idx);
	else
		return F(T, mid, R, id * 2 + 1, idx) + T[id * 2];
}

int G(int L, int R, int id, int idx){
	Ts[id] ++;
	if(R - L == 1){
		if(idx != 1)
			return R;
		return L;
	}
	int mid = (L + R) >> 1;
	if(mid - L - Ts[id * 2] >= idx)
		return G(L, mid, id * 2, idx);
	else
		return G(mid, R, id * 2 + 1, idx - (mid - L - Ts[id * 2]));
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	int a[n + 1], b[n + 1];
	rep(i, n)
		cin >> a[i];
	rep(i, n)
		cin >> b[i];
	rep(i, n){
		af[n - i - 1] = a[i] - F(Ta, 0, n, 1, a[i]);
		bf[n - i - 1] = b[i] - F(Tb, 0, n, 1, b[i]);
	}

	rep(i, n){
		sf[i] += af[i] + bf[i];
		sf[i + 1] += sf[i] / (i + 1);
		sf[i] %= i + 1;
	}

	for(int i = n - 1; i >= 0; i--)
		s[n - i - 1] = G(0, n, 1, sf[i] + 1);
	rep(i, n)
		cout << s[i] << ' ';
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, t) for(ll (i) = 0; (i) < (ll)(t); (i)++)
#define reu(i, s, e) for(ll (i) = (ll)(s); (i) <= (ll)(e); (i)++)
#define rer(i, s, e) for(ll (i) = (ll)(s); (i) < (ll)(e); (i)++)
#define For(i, v) for(__typeof((v).begin()) (i) = (v).begin(); (i) != (v).end(); (i) ++)
#define mset(arr, val) memset(arr, (val), sizeof arr)
#define PB push_back
#define MP make_pair
#define p1 first
#define p2 second

typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<int, int> pie;

const int maxn = 2e5 + 10;
int af[maxn], bf[maxn], sf[maxn];
int Ta[2 * maxn], Tb[2 * maxn], Ts[2 * maxn];
int s[maxn];

int F(int *T, int L, int R, int id, int idx){
	T[id] ++;
	if(R - L == 1)
		return 0;
	int mid = (L + R) >> 1;
	if(idx < mid)
		return F(T, L, mid, id * 2, idx);
	else
		return F(T, mid, R, id * 2 + 1, idx) + T[id * 2];
}

int G(int L, int R, int id, int idx){
	Ts[id] ++;
	if(R - L == 1){
		return L;
	}
	int mid = (L + R) >> 1;
	if(mid - L - Ts[id * 2] > idx)
		return G(L, mid, id * 2, idx);
	else
		return G(mid, R, id * 2 + 1, idx - (mid - L - Ts[id * 2]));
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	int a[n + 1], b[n + 1];
	rep(i, n)
		cin >> a[i];
	rep(i, n)
		cin >> b[i];
	rep(i, n){
		af[n - i - 1] = a[i] - F(Ta, 0, n, 1, a[i]);
		bf[n - i - 1] = b[i] - F(Tb, 0, n, 1, b[i]);
	}

	rep(i, n){
		sf[i] += af[i] + bf[i];
		sf[i + 1] += sf[i] / (i + 1);
		sf[i] %= i + 1;
	}

	for(int i = n - 1; i >= 0; i--)
		s[n - i - 1] = G(0, n, 1, sf[i]);
	rep(i, n)
		cout << s[i] << ' ';
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, t) for(ll (i) = 0; (i) < (ll)(t); (i)++)
#define reu(i, s, e) for(ll (i) = (ll)(s); (i) <= (ll)(e); (i)++)
#define rer(i, s, e) for(ll (i) = (ll)(s); (i) < (ll)(e); (i)++)
#define For(i, v) for(__typeof((v).begin()) (i) = (v).begin(); (i) != (v).end(); (i) ++)
#define mset(arr, val) memset(arr, (val), sizeof arr)
#define PB push_back
#define MP make_pair
#define p1 first
#define p2 second

typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<int, int> pie;

const int maxn = 2e5 + 10;
int af[maxn], bf[maxn], sf[maxn];
int Ta[2 * maxn], Tb[2 * maxn], Ts[2 * maxn];
int s[maxn], n;

int F(int *T, int L, int R, int id, int idx){
	T[id] ++;
	if(R - L == 1)
		return 0;
	int mid = (L + R) >> 1;
	if(idx < mid)
		return F(T, L, mid, id * 2, idx);
	else
		return F(T, mid, R, id * 2 + 1, idx) + T[id * 2];
}

int G(int L, int R, int id, int idx){
	Ts[id] --;
	if(R - L == 1)
		return L;
	int mid = (L + R) >> 1;
	if(Ts[id * 2] >= idx)
		return G(L, mid, id * 2, idx);
	else
		return G(mid, R, id * 2 + 1, idx - Ts[id * 2]);
}

void setG(int L = 0, int R = n, int id = 1){
	Ts[id] = R - L;
	if(R - L == 1)
		return;
	int mid = (L + R) >> 1;
	setG(L, mid, id * 2);
	setG(mid, R, id * 2 + 1);
}

int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	int a[n + 1], b[n + 1];
	rep(i, n)
		cin >> a[i];
	rep(i, n)
		cin >> b[i];
	rep(i, n){
		af[n - i - 1] = a[i] - F(Ta, 0, n, 1, a[i]);
		bf[n - i - 1] = b[i] - F(Tb, 0, n, 1, b[i]);
	}

	rep(i, n){
		sf[i] += af[i] + bf[i];
		sf[i + 1] += sf[i] / (i + 1);
		sf[i] %= i + 1;
	}

	setG();
	for(int i = n - 1; i >= 0; i--)
		s[n - i - 1] = G(0, n, 1, sf[i] + 1);
	rep(i, n)
		cout << s[i] << ' ';
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, t) for(ll (i) = 0; (i) < (ll)(t); (i)++)
#define reu(i, s, e) for(ll (i) = (ll)(s); (i) <= (ll)(e); (i)++)
#define rer(i, s, e) for(ll (i) = (ll)(s); (i) < (ll)(e); (i)++)
#define For(i, v) for(__typeof((v).begin()) (i) = (v).begin(); (i) != (v).end(); (i) ++)
#define mset(arr, val) memset(arr, (val), sizeof arr)
#define PB push_back
#define MP make_pair
#define p1 first
#define p2 second

typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<int, int> pie;

const int maxn = 2e5 + 10;
int af[maxn], bf[maxn], sf[maxn];
int Ta[2 * maxn], Tb[2 * maxn], Ts[2 * maxn];
int s[maxn], n;

int F(int *T, int L, int R, int id, int idx){
	T[id] --;
	if(R - L == 1)
		return 0;
	int mid = (L + R) / 2;
	if(idx < mid)
		return F(T, L, mid, id * 2, idx);
	else
		return F(T, mid, R, id * 2 + 1, idx) + T[id * 2];
}

int G(int L, int R, int id, int idx){
	Ts[id] --;
	if(R - L == 1)
		return L;
	int mid = (L + R) / 2;
	if(Ts[id * 2] >= idx)
		return G(L, mid, id * 2, idx);
	else
		return G(mid, R, id * 2 + 1, idx - Ts[id * 2]);
}

void setT(int *T, int L = 0, int R = n, int id = 1){
	T[id] = R - L;
	if(R - L == 1)
		return;
	int mid = (L + R) >> 1;
	setT(T, L, mid, id * 2);
	setT(T, mid, R, id * 2 + 1);
}

int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	int a[n + 1], b[n + 1];
	rep(i, n)
		cin >> a[i];
	rep(i, n)
		cin >> b[i];
	setT(Ta);
	setT(Tb);
	rep(i, n){
		af[n - i - 1] = F(Ta, 0, n, 1, a[i]);
		bf[n - i - 1] = F(Tb, 0, n, 1, b[i]);
	}

	rep(i, n){
		sf[i] += af[i] + bf[i];
		sf[i + 1] = sf[i] / (i + 1);
		sf[i] %= (i + 1);
	}

	setT(Ts);
	for(int i = n - 1; i >= 0; i--)
		s[n - i - 1] = G(0, n, 1, sf[i] + 1);
	rep(i, n)
		cout << s[i] << ' ';
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, t) for(ll (i) = 0; (i) < (ll)(t); (i)++)
#define reu(i, s, e) for(ll (i) = (ll)(s); (i) <= (ll)(e); (i)++)
#define rer(i, s, e) for(ll (i) = (ll)(s); (i) < (ll)(e); (i)++)
#define For(i, v) for(__typeof((v).begin()) (i) = (v).begin(); (i) != (v).end(); (i) ++)
#define mset(arr, val) memset(arr, (val), sizeof arr)
#define PB push_back
#define MP make_pair
#define p1 first
#define p2 second

typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<int, int> pie;

const int maxn = 2e5 + 10;
int af[maxn], bf[maxn], sf[maxn];
int Ta[2 * maxn], Tb[2 * maxn], Ts[2 * maxn];
int s[maxn];

int F(int *T, int L, int R, int id, int idx){
	T[id] ++;
	if(R - L == 1)
		return 0;
	int mid = (L + R) >> 1;
	if(idx < mid)
		return F(T, L, mid, id * 2, idx);
	else
		return F(T, mid, R, id * 2 + 1, idx) + T[id * 2];
}

int G(int L, int R, int id, int idx){
	Ts[id] ++;
	if(R - L == 1){
		return L;
	}
	int mid = (L + R) >> 1;
	if(mid - L - Ts[id * 2] >= idx)
		return G(L, mid, id * 2, idx);
	else
		return G(mid, R, id * 2 + 1, idx - (mid - L - Ts[id * 2]));
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	int a[n + 1], b[n + 1];
	rep(i, n)
		cin >> a[i];
	rep(i, n)
		cin >> b[i];
	rep(i, n){
		af[n - i - 1] = a[i] - F(Ta, 0, n, 1, a[i]);
		bf[n - i - 1] = b[i] - F(Tb, 0, n, 1, b[i]);
	}

	rep(i, n){
		sf[i] += af[i] + bf[i];
		sf[i + 1] += sf[i] / (i + 1);
		sf[i] %= i + 1;
	}

	for(int i = n - 1; i >= 0; i--)
		s[n - i - 1] = G(0, n, 1, sf[i] + 1);
	rep(i, n)
		cout << s[i] << ' ';
	cout << endl;
	return 0;
}