[贪心][优先队列]Productive Meeting Codeforces1579D

An important meeting is to be held and there are exactly nn people invited. At any moment, any two people can step back and talk in private. The same two people can talk several (as many as they want) times per meeting.

Each person has limited sociability. The sociability of the ii-th person is a non-negative integer aiai. This means that after exactly aiai talks this person leaves the meeting (and does not talk to anyone else anymore). If ai=0ai=0, the ii-th person leaves the meeting immediately after it starts.

A meeting is considered most productive if the maximum possible number of talks took place during it.

You are given an array of sociability aa, determine which people should talk to each other so that the total number of talks is as large as possible.

Input

The first line contains an integer tt (1≤t≤10001≤t≤1000) — the number of test cases.

The next 2t2t lines contain descriptions of the test cases.

The first line of each test case description contains an integer nn (2≤n≤2⋅1052≤n≤2⋅105) —the number of people in the meeting. The second line consists of nn space-separated integers a1,a2,…,ana1,a2,…,an (0≤ai≤2⋅1050≤ai≤2⋅105) — the sociability parameters of all people.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105. It is also guaranteed that the sum of all aiai (over all test cases and all ii) does not exceed 2⋅1052⋅105.

Output

Print tt answers to all test cases.

On the first line of each answer print the number kk — the maximum number of talks possible in a meeting.

On each of the next kk lines print two integers ii and jj (1≤i,j≤n1≤i,j≤n and i≠ji≠j) — the numbers of people who will have another talk.

If there are several possible answers, you may print any of them.

Example

input

Copy

8
2
2 3
3
1 2 3
4
1 2 3 4
3
0 0 2
2
6 2
3
0 0 2
5
8 2 0 1 1
5
0 1 0 0 6

output

Copy

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

题意: 有n个人,每人拥有一个权值a[i],你可以任选两人开展对话,并使他们的a[i]分别减一,当某人a[i]减到0时他就要退出这场会议,询问最多能开展对话次数。

分析: 类似之前做过的一道题:电池的寿命 Bailian3468,如果用那道题的思路会更加简单。这道题也是贪心的思想,我们不希望有人退出会议(退出会议代表选择变少了,更容易出现剩一个人权值很大的情况),因此每次都取拥有最大a[i]的和次大a[i]的两个人开展对话,这样一定是最优的,具体实现可以通过优先队列,由于所有样例的a[i]加和小于2e5,nlogn复杂度并不会超时。但是要注意不能选择两人以后一直让他们进行对话,这样并不是最优,例如有三个人,a[i]都是4,显然答案会是6,但如果选最大的和次大的一直对话会得到4。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;

struct node
{
	int num, pos;
}a[200005];

struct cmp
{
	bool operator()(const node &q, const node &w)
	{
		return q.num < w.num;
	}
};

int l[200005], r[200005], ans;

signed main()
{
	int T;
	cin >> T;
	while(T--)
	{
		priority_queue<node, vector<node>, cmp> q; 
		ans = 0;
		int n;
		cin >> n;
		for(int i = 1; i <= n; i++)
		{
			scanf("%d", &a[i].num);
			a[i].pos = i;
			if(a[i].num >= 1)
				q.push(a[i]);
		}
		while(q.size() >= 2)
		{
			node t1 = q.top();
			q.pop();
			node t2 = q.top();
			q.pop();
			t1.num--;
			t2.num--;
			l[++ans] = min(t1.pos, t2.pos);
			r[ans] = max(t1.pos, t2.pos);
			if(t1.num >= 1)
				q.push(t1);
			if(t2.num >= 1)
				q.push(t2);
		}
		printf("%d\n", ans);
		for(int i = 1; i <= ans; i++)
			printf("%d %d\n", l[i], r[i]);
	}
    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值