Codeforces 798D Mike and distribution (构造 + 脑洞 推荐)

来源:互联网 发布:山海经 美洲 知乎 编辑:程序博客网 时间:2024/05/21 11:29

D. Mike and distribution
time limit per test
2 seconds
memory limit per test
256 megabytes

Mike has always been thinking about the harshness of social inequality. He's so obsessed with it that sometimes it even affects him while solving problems. At the moment, Mike has two sequences of positive integers A = [a1, a2, ..., an] and B = [b1, b2, ..., bn] of length neach which he uses to ask people some quite peculiar questions.

To test you on how good are you at spotting inequality in life, he wants you to find an "unfair" subset of the original sequence. To be more precise, he wants you to select k numbers P = [p1, p2, ..., pk] such that 1 ≤ pi ≤ n for 1 ≤ i ≤ k and elements in P are distinct. Sequence P will represent indices of elements that you'll select from both sequences. He calls such a subset P "unfair" if and only if the following conditions are satisfied: 2·(ap1 + ... + apk) is greater than the sum of all elements from sequence A, and 2·(bp1 + ... + bpk) is greaterthan the sum of all elements from the sequence B. Also, k should be smaller or equal to  because it will be to easy to find sequence P if he allowed you to select too many elements!

Mike guarantees you that a solution will always exist given the conditions described above, so please help him satisfy his curiosity!

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of elements in the sequences.

On the second line there are n space-separated integers a1, ..., an (1 ≤ ai ≤ 109) — elements of sequence A.

On the third line there are also n space-separated integers b1, ..., bn (1 ≤ bi ≤ 109) — elements of sequence B.

Output

On the first line output an integer k which represents the size of the found subset. k should be less or equal to .

On the next line print k integers p1, p2, ..., pk (1 ≤ pi ≤ n) — the elements of sequence P. You can print the numbers in any order you want. Elements in sequence P should be distinct.

Example
input
58 7 4 8 34 2 5 3 7
output
31 4 5
题目链接:http://codeforces.com/contest/798/problem/D

题目大意:两个长度为n的数列A,B,要求至多选择n/2 +1个下标,使得A中选出的数的和的两倍大于sumA,B中选出的数的和的两倍大于sumB

题目分析:题目的意思其实就是要求两个数组选出的数的和分别大于它们剩下的数的和,这个题目有点难想,抓住关键点:最多可以取n/2+1个数!,其实这个最多是多余的,显然是取得越多越好,先将A从大到小排序,把第一个即A中最大的取出,同时对应下标的B中也取出一个,接下来,根据A排序后的序列将剩余的两两分组,每组中选B大的那个,按照这个策略一直选下去,如果n为偶数,则将最后剩余的那个也取出。说明一下样例,排序后:

A  8  8  7  4  3

B  4  3  2  5  7

id 1  4  2  3  5

先选A的8,同时选出B的4,id为1,接着比较B的3和2, 3大,因此选择的id为4,最后比较B的5和7,7大,因此选择的id为5,故答案为1 4 5。接下来证明这样做的正确性。

首先证明B数组,B中与A的最大的一起先选出了一个,接下来两两分组中我们都选大的,显然选出的值的和要大于剩余的值的和,即B数组满足条件。再看A,A中选出了一个最大的maxA,接下来我们考虑最坏的情况,两两分组在B中选择的大的数的下标对应的A中选出的均是小的那个,但是由于我们可以选n/2+1个数,且已把最大的取出,这样我们可以进行错位比较,即

maxA > max(A[2], A[3])  (此处下标指从大到小排完序后的)

min(A[2], A[3]) > max(A[4], A[5])

......

min(A[i], A[i + 1]) > max(A[i + 2], A[i + 3])

将上面所有式子相加可证A数组也满足。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int const MAX = 1e5 + 5;int n, ans[MAX];struct DATA {    int a, b, id;}d[MAX];bool cmp(DATA d1, DATA d2) {    return d1.a > d2.a;}int main() {    scanf("%d", &n);    for (int i = 0; i < n; i ++) {        scanf("%d", &d[i].a);    }    for (int i = 0; i < n; i ++) {        scanf("%d", &d[i].b);        d[i].id = i;    }    sort(d, d + n, cmp);    int num = n / 2 + 1, cnt = 0;    ans[cnt ++] = d[0].id;    for (int i = 1; i + 1 < n; i += 2) {        if (d[i].b < d[i + 1].b) {            ans[cnt ++] = d[i + 1].id;        } else {            ans[cnt ++] = d[i].id;        }    }    if (!(n & 1)) {        ans[cnt ++] = d[n - 1].id;    }    printf("%d\n", num);    for (int i = 0; i < num - 1; i ++) {        printf("%d ", ans[i] + 1);    }    printf("%d\n", ans[num - 1] + 1);}




阅读全文
1 0
原创粉丝点击