Solution
我们可以分组。将 a a a 和 b b b 捆绑在一起,并把 a a a 从大到小排序。
然后分奇偶讨论。
- n n n 为奇。必选第一个,然后再将后面两两分组,选择每组中最大的 b b b。
- n n n 为偶。必选第一和第二个,然后再将后面两两分组,选择每组中最大的 b b b。
首先证明符合 a a a 的条件。如果第一组选的编号的 a a a 较小,可以用最大的 a a a 来比下去,然后对于后面的每个数,这个较小的 a a a 总是可以比下去。
同时也符合 b b b 的条件。首先我们后面的分组保证了 b b b 是不小于的。那么前面相当于多选了一个 b b b,肯定就是大于了。
Code
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
int n;
vector <int> ans;
struct node {int a, b, id;} s[N];
int read() {
int x = 0, f = 1; char s;
while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
while(s >= '0' && s <= '9') x = (x << 1) + (x << 3) + (s ^ 48), s = getchar();
return x * f;
}
bool cmp(const node x, const node y) {return x.a > y.a;}
int main() {
n = read();
for(int i = 1; i <= n; ++ i) s[i].a = read(), s[i].id = i;
for(int i = 1; i <= n; ++ i) s[i].b = read();
sort(s + 1, s + n + 1, cmp);
if(n & 1) {
ans.push_back(1);
for(int i = 2; i <= n; i += 2)
if(s[i].b > s[i + 1].b) ans.push_back(i);
else ans.push_back(i + 1);
}
else {
ans.push_back(1); ans.push_back(2);
for(int i = 3; i <= n; i += 2)
if(s[i].b > s[i + 1].b) ans.push_back(i);
else ans.push_back(i + 1);
}
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); ++ i) printf("%d ", s[ans[i]].id); puts("");
return 0;
}