D. Mike and distribution

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

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. SequenceP 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 greater than 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
5
8 7 4 8 3
4 2 5 3 7
output
3
1 4 5

感觉从这道题中收获很大,首先是学会了优先队列的使用,对于优先队列的运算符重载有了新的认识,尤其是大根堆的<的重载,我之前一直以为应该是用>的,还有就是优先队列的读入,比如:

que.push((node1){re[i].x,re[i].y,re[i].id}); 真的是极其巧妙。

再说一下这道题的解题思路:这道题题目中要求选的k的长度不能大于等于,再加上题目的要求,K的大小其实就是,当然了,k的值也可以更小,单就做出这道题来说,K就等于

当n无论是even number还是odd number,K的值都表示我们选取的长度比n的一半要长。。。。我似乎说了一大堆废话,但我不这么觉得,因为K的取值在我解决这道题的过程中起着很关键的作用。接下来就是这道题的两个解题关键点了:

1:先对A排序,B也随之排序(B还是乱序的,只是跟着A的排序而排序)。

2:然后两个两个的进行选择B。例如 b[i] b[i+1]这样。选择方案为max(b[i],b[i+1]);

对A进行排序是保证两个两个选的时候A的选择肯定符合题目要求,这里要注意,一定先把下标为一选出来。很关键。而B的这种选择操作我们也很容易知道为什么。


#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
int book[100005];
ll sumx,sumy;
struct node
{
    int x;
    int y;
    int id;
}re[100005],rt[100005];

struct node1
{
    int x,y;
    int id;

    friend bool operator < (node1 a,node1 b) //大根堆重载的是<号!!!
    {
        if(a.y == b.y)
        return a.x<b.x;

        return a.y < b.y;
    }
};

int cmp(node a,node b)
{
    if(a.x == b.x)
    return a.y>b.y;

    return a.x>b.x;
}
int main()
{
    cin>>n;
    int i,j;
    sumx=0;
    sumy=0;
    for(i=1;i<=n;i++)
    cin>>rt[i].x;
    for(i=1;i<=n;i++)
    cin>>rt[i].y;
    for(i=1;i<=n;i++)
    {
        re[i].x=rt[i].x;
        re[i].y=rt[i].y;
        sumx+=re[i].x;
        sumy+=re[i].y;
        re[i].id=i;
    }

    sort(re+1,re+n+1,cmp);
    memset(book,0,sizeof(book));
    priority_queue<node1> que;
    book[re[1].id]=1;  //这个不要忘
    struct node1 temp;
    for(i=2;i<=n;i+=2)  //注意下标是从2开始的。
    {
        que.push((node1){re[i].x,re[i].y,re[i].id});  //要记住这种形式
        que.push((node1){re[i+1].x,re[i+1].y,re[i+1].id});
        temp=que.top();
        sumx-= temp.x*2;
        sumy-= temp.y*2;
        book[temp.id] = 1;
        que.pop();
        que.pop();

        if(sumx<0 && sumy<0)
        break;
    }

    if(n%2==0)  //这一步也很关键,这其实就是我题解中讲到的K的取值问题,就关系在这。
    {
        book[que.top().id]=1;
    }

    int ans=0;
    for(i=1;i<=n;i++)
    {
        if(book[i]==1)
        ans++;
    }

    cout<<ans<<endl;

    for(i=1;i<=n;i++)
    if(book[i]==1)
    cout<<i<<" ";
    cout<<endl;
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值