Gym 101484D Joaozao, The Digit Maker

D. Joaozao, The Digit Maker
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

Joaozao is a famous digit maker in the city of Sao Carlos. He owns a shop downtown where he receives orders to create numbers. Nicoleta, his friend and a very recent hire, is trying to learn this fancy art of digit making.

Joaozao is specialized in making numbers in base B. A number in base B is a sequence of digits written in the following way:

xb = d1d2d3... dm, 

where 0 ≤ di < B for i = 1, 2, ... m.

Joaozao received an order to build an n-digit number in base B. It is a lot of work for one day, so he decided to ask Nicoleta, who is still learning, to help him.

The process of building the number is the following: First Joaozao creates 2n digits in base B. After that, Joaozao gives pairs of digits to Nicoleta, one after the other. As Nicoleta receives them, he adds these two digits together and takes the remainder of the division by B, creating a new digit z. Finally, Nicoleta attaches z to the beginning of the number they are building, making z its most significant digit. After n steps, they will have an n-digit number written in base B.

Joaozao has already created 2n digits in base B and they will soon start the next step of the process. They are wondering what is the largest number they can build (the larger the number, the more valuable it is). Nicoleta really wants to impress Joaozao, so he asked you to help him with this task.

Input

The first line of the input contains two integers n (1 ≤ n ≤ 105) and B (1 ≤ B ≤ 109), indicating respectively the number of digits of the number Nicoleta will build and its base.

The second line contains 2n integers di representing the digits Joaozao has already created. (0 ≤ di ≤ B - 1).

Output

Output n space separated integers: the digits of the largest number in base B that Joaozao and Nicoleta can build, from most significant to least significant.

If this number has leading zeros, output them anyway.

Examples
input
3 10
1 2 3 4 5 6
output
9 9 3 
input
2 19
1 2 16 17
output
18 18 
Note

A number xb = d1d2...dm is larger than yb = r1r2...rp. If, and only if,


题意:有2n个数,和一个B,要把这2n个数两两配对,得到n对,每个数用一次,每一对的数相加对B求余就是这一对的值,这n个值可以构成一个n位的数,求最大的数是多少
题解:对于每一个数,想找和它相加小于B的那个最大的数,构成一对,然后每次拿出这一对,先看看其中的v有没有被使用过,再找到现在剩下的数中和它相加值最大的那个数,然后标记输出


代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
ll n,MOD;
const int N=2e5+10;
ll a[N],p[N];
ll pre[N];//如果i的p[i]已经被使用了 ,下一个的应该找的位置
ll used[N]; // 标记是否已经匹配成功
ll fun(ll u){
	/*while (used[u]){
		u=pre[u];
	}*/ //会TLE
	if (used[u]){
		return pre[u]=fun(pre[u]);
	}
	else return u;

}
int main (){
	scanf ("%lld%lld",&n,&MOD);
	for (int i=0;i<2*n;i++) scanf ("%lld",&a[i]);
	sort(a,a+2*n);
	priority_queue<P> q;
	for(int i=0;i<2*n;i++){
		ll t=lower_bound(a,a+2*n,MOD-a[i])-a;
		p[i]=(t-1+2*n)%(2*n); //得到与a[i]相加余数最大的的位置
		q.push(P((a[i]+a[p[i]])%MOD,i));
	}
	n*=2;
	while(!q.empty()){
		P now=q.top();
		q.pop();
		ll u=now.first;
		ll v=now.second;
		if (used[v]) continue;
		p[v]=fun(p[v]);
		if (p[v]==v){
			p[v]=fun((p[v]-1+n)%n);
			if (p[v]==v) continue;//因为一个数只能用一遍
		}
		if((a[v]+a[p[v]])%MOD!=u){
			q.push(P((a[v]+a[p[v]])%MOD,v));
		}
		else {
			printf ("%lld ",u);
			used[v]=1;
			used[p[v]]=1;
			pre[v]=(v-1+n)%n;
			pre[p[v]]=(p[v]-1+n)%n;
		}
	}
	printf ("\n");


	return 0;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值