Loading

Codeforces Global Round 14 C. Phoenix and Towers(贪心/优先队列)

Phoenix has n blocks of height h1,h2,…,hn, and all hi don't exceed some value x. He plans to stack all 𝑛n blocks into m separate towers. The height of a tower is simply the sum of the heights of its blocks. For the towers to look beautiful, no two towers may have a height difference of strictly more than x.

Please help Phoenix build m towers that look beautiful. Each tower must have at least one block and all blocks must be used.

Input

The input consists of multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases.

The first line of each test case contains three integers n, m, and x (1≤m≤n≤10^5; 1≤x≤10^4) — the number of blocks, the number of towers to build, and the maximum acceptable height difference of any two towers, respectively.

The second line of each test case contains n space-separated integers (1≤hi≤x) — the heights of the blocks.

It is guaranteed that the sum of n over all the test cases will not exceed 10^5.

Output

For each test case, if Phoenix cannot build m towers that look beautiful, print NO. Otherwise, print YES, followed by n integers y1,y2,…,yn, where yi (1≤yi≤m) is the index of the tower that the i-th block is placed in.

If there are multiple solutions, print any of them.

Example

input

Copy

2
5 2 3
1 2 3 1 2
4 3 3
1 1 2 3

output

Copy

YES
1 1 1 2 2
YES
1 2 2 3

堆贪心,每次从当前堆中取出高度最小的塔,将当前块加上去即可。证明如下:当有两个塔高度相差超过x时,因为每个块的高度小于x,因此相差的必定为两个块以上,而由贪心策略每次都是往最矮的塔上面放,不可能出现相差两个块的情况(模拟一下易知)。

#include <bits/stdc++.h>
using namespace std;
int n, m, x;
int b[100005], tower[100005], ans[100005];
struct node {
	int id, h;
	bool operator < (const node &o) const {
		return h > o.h;
	}
};

int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> m >> x;
		priority_queue<node> q;
		for(int i = 1; i <= n; i++) {
			cin >> b[i];
		}
		for(int i = 1; i <= m; i++) tower[i] = 0;
		//要求所有塔的最大值和最小值相差不超过x
		for(int i = 1; i <= m; i++) {
			node now = {i, 0};
			q.push(now);
		}
		for(int i = 1; i <= n; i++) {
			node now = q.top();
			q.pop();
			ans[i] = now.id;//注意这里的b数组是已经排序过的
			now.h += b[i];
			q.push(now);
		}
		int minn = 0x3f3f3f3f, maxx = 0;
		while(q.size()) {
			node now = q.top(); q.pop();
			minn = min(minn, now.h);
			maxx = max(maxx, now.h);
		}
		if(maxx - minn > x || !minn || !maxx) {
			cout << "NO" << endl;
			continue;
		}
		cout << "YES" << endl;
		for(int i = 1; i <= n; i++) {
			cout << ans[i] << " ";
		}
		cout << endl;
	}
	return 0;
}
posted @ 2021-05-03 22:12  脂环  阅读(162)  评论(0编辑  收藏  举报