首页 > 编程语言 > 详细

Codeforces 501D. Misha and Permutations Summation 康拓展开+树状数组+二分

时间:2015-03-25 23:35:49      阅读:558      评论:0      收藏:0      [点我收藏+]


康拓展开+树状数组+二分:   详解

D. Misha and Permutations Summation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Let‘s define the sum of two permutations p and q of numbers 0,?1,?...,?(n?-?1) as permutation 技术分享, where Perm(x) is the x-th lexicographically permutation of numbers 0,?1,?...,?(n?-?1) (counting from zero), and Ord(p) is the number of permutation p in the lexicographical order.

For example, Perm(0)?=?(0,?1,?...,?n?-?2,?n?-?1)Perm(n!?-?1)?=?(n?-?1,?n?-?2,?...,?1,?0)

Misha has two permutations, p and q. Your task is to find their sum.

Permutation a?=?(a0,?a1,?...,?an?-?1) is called to be lexicographically smaller than permutation b?=?(b0,?b1,?...,?bn?-?1), if for some k following conditions hold: a0?=?b0,?a1?=?b1,?...,?ak?-?1?=?bk?-?1,?ak?<?bk.

Input

The first line contains an integer n (1?≤?n?≤?200?000).

The second line contains n distinct integers from 0 to n?-?1, separated by a space, forming permutation p.

The third line contains n distinct integers from 0 to n?-?1, separated by spaces, forming permutation q.

Output

Print n distinct integers from 0 to n?-?1, forming the sum of the given permutations. Separate the numbers by spaces.

Sample test(s)
input
2
0 1
0 1
output
0 1
input
2
0 1
1 0
output
1 0
input
3
1 2 0
2 1 0
output
1 0 2
Note

Permutations of numbers from 0 to 1 in the lexicographical order: (0,?1),?(1,?0).

In the first sample Ord(p)?=?0 and Ord(q)?=?0, so the answer is 技术分享.

In the second sample Ord(p)?=?0 and Ord(q)?=?1, so the answer is 技术分享.

Permutations of numbers from 0 to 2 in the lexicographical order: (0,?1,?2),?(0,?2,?1),?(1,?0,?2),?(1,?2,?0),?(2,?0,?1),?(2,?1,?0).

In the third sample Ord(p)?=?3 and Ord(q)?=?5, so the answer is 技术分享.


/* ***********************************************
Author        :CKboss
Created Time  :2015年03月25日 星期三 18时57分39秒
File Name     :CF501D.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int maxn=200200;

int n;
int a[maxn],b[maxn],c[3][maxn];

/************************************/

int sum[maxn];

int lowbit(int x) { return x&(-x); }

void add(int p,int v=1)
{
	for(int i=p;i<=n;i+=lowbit(i)) sum[i]+=v;
}

int get(int p)
{
	int ret=0;
	for(int i=p;i;i-=lowbit(i)) ret+=sum[i];
	return ret;
}

/************************************/

bool on[maxn];

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	scanf("%d",&n);
	for(int i=0;i<n;i++) 
	{
		scanf("%d",a+i); a[i]++;
		int before=get(a[i]);
		c[0][i]=a[i]-1-before;
		add(a[i]);
	}

	memset(sum,0,sizeof(sum));
	for(int i=0;i<n;i++) 
	{
		scanf("%d",b+i); b[i]++;
		int before=get(b[i]);
		c[1][i]=b[i]-1-before;
		c[2][i]=c[0][i]+c[1][i];
		add(b[i]);
	}

	for(int i=n-1;i>0;i--)
	{
		int j=n-1-i;
		if(c[2][i]>j) 
		{
			c[2][i]-=j+1; c[2][i-1]++;
		}
	}
	c[2][0]%=n;


	memset(sum,0,sizeof(sum));
	memset(on,true,sizeof(on));

	for(int i=1;i<=n;i++) add(i);

	vector<int> vi;

	for(int i=0;i<n;i++)
	{
		int goal=c[2][i];
		int low=0,high=n,ans=-1;

		while(low<=high)
		{
			int mid=(low+high)/2;
			int s=get(mid);

			if(s==goal)
			{
				if(on[mid+1]==true)
				{
					ans=mid+1; break;
				}
				else low=mid+1;
			}
			else if(s<goal) low=mid+1;
			else if(s>goal) high=mid-1;
			
		}
		on[ans]=false; add(ans,-1);
		vi.push_back(ans-1);
	}

	for(int i=0;i<n;i++) printf("%d ",vi[i]);
	putchar(10);
    
    return 0;
}





Codeforces 501D. Misha and Permutations Summation 康拓展开+树状数组+二分

原文:http://blog.csdn.net/ck_boss/article/details/44629799

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!