CF Round410 D. Mike and distribution

D. Mike and distribution 构造法

798D - Mike and distribution

In the beginning, it‘s quite easy to notice that the condition " 2·(ap1?+?...?+?apk) is greater than the sum of all elements in A " is equivalent to " ap1?+?...?+?apk is greater than the sum of the remaining elements in A ".

Now, let‘s store an array of indices C with Ci?=?i and then sort it in decreasing order according to array A, that is we must have ACi?≥?ACi?+?1.

Our answer will always have size . First suppose that N is odd. Add the first index to our set, that is make p1?=?C1. Now, for the remaining elements, we will consider them consecutively in pairs. Suppose we are at the moment inspecting AC2k and AC2k?+?1. If BC2k?≥?BC2k?+?1 we make pk?+?1?=?C2k, else we make pk?+?1?=?C2k?+?1.

Why does this subset work? Well, it satisfies the condition for B because each time for consecutive non-intersecting pairs of elements we select the bigger one, and we also add BC1 to the set, so in the end the sum of the selected elements will be bigger than the sum of the remaining ones.

It also satisfies the condition for A, because Ap1 is equal or greater than the complement element of p2 (that is — the index which we could‘ve selected instead of p2 from the above procedure — if we selected C2k then it would be C2k?+?1 and vice-versa). Similarly Ap2 is greater than the complement of p3 and so on. In the end we also add the last element from the last pair and this makes the sum of the chosen subset strictly bigger than the sum of the remaining elements.

The case when N is even can be done exactly the same as when N is odd, we just pick the last remaining index in the end.

The complexity is .

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 7;
int a[N], b[N], c[N], p[N/2];
bool cmp(int i, int j) {
    return a[i] > a[j];
}
int main()
{
    //ios::sync_with_stdio(0);
    int n;
    while(~scanf("%d", &n)) {
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a +i);
            c[i] = i;
        }
        for (int i = 1; i <= n; ++i)
            scanf("%d", b + i);
        sort(c + 1, c + 1 + n, cmp);
        int k = n + 1 >> 1, cur = 0;
        p[++cur] = c[1];
        b[n + 1] = 0;//最边界小值
        for (int i = 2; i <= n; i += 2)  //cur = k ?
                p[++cur] = b[c[i]] > b[c[i + 1]] ? c[i] : c[i+1];
        printf("%d\n%d", cur, p[1]);
        for (int i = 2; i <= cur; ++i)
            printf(" %d", p[i]);
        puts("");
    }

    return 0;
}
时间: 2024-10-13 18:58:34

CF Round410 D. Mike and distribution的相关文章

CF Round410 C. Mike and gcd problem

C. Mike and gcd problem 一奇一偶需要两次操作,两个奇数需要一次操作. 798D - Mike and distribution In the beginning, it's quite easy to notice that the condition " 2·(ap1?+?...?+?apk) is greater than the sum of all elements in A " is equivalent to " ap1?+?...?+?a

Codeforces 798D Mike and distribution(贪心或随机化)

题目链接 Mike and distribution 题目意思很简单,给出$a_{i}$和$b_{i}$,我们需要在这$n$个数中挑选最多$n/2+1$个,使得挑选出来的 $p_{1}$,$p_{2}$,$p_{3}$,...,$p_{m}$满足 $a_{p1}+a_{p2}+a_{p3}+...+a_{p_{m}}>a_{1}+a_{2}+a_{3}+...+a_{n}$ $b_{p1}+b_{p2}+b_{p3}+...+b_{p_{m}}>b_{1}+b_{2}+b_{3}+...+b_

Codeforces 798D Mike and distribution - 贪心

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, 

Codeforces 798D:Mike and distribution

Codeforces 798D:Mike and distributio 题目链接:http://codeforces.com/problemset/problem/798/D 题目大意:给出两个大小为$n$的数列$A,B$,现要求从这两个数列相同位置取出$K(K \leqslant n/2+1)$个数,使得$2 \times subA>sumA$且$2 \times subB>sumB$. 想法题 我们需要从数列$A$和数列$B$中取出$K$个数,使得这$K$个数的和比剩下$n-K$个数的和

CF 547 D. Mike and Fish

D. Mike and Fish http://codeforces.com/contest/547/problem/D 题意: 给定平面上n个点,将这些点染成红或者蓝色,要求每行.每列红色点与蓝色点数量的差的绝对值<=1.输出方案(保证有解). 分析: 参考popoqqq的博客 将每行每列分别看做一个点,给定的每个点(x,y)拆成x->y的边,那么连边后的图是一个二分图. 这样我们可以将边染色,使得与每个点相连的两种颜色差<=1. 于是对于所有的欧拉回路,我们可以直接交替染色. 但是会

【算法系列学习】codeforces D. Mike and distribution 二维贪心

http://codeforces.com/contest/798/problem/D http://blog.csdn.net/yasola/article/details/70477816 对于二维的贪心我们可以先让它变成其中一维有序,这样只需要重点考虑另一维,就会简单很多. 首先,对于题目要求的选择元素之和两倍大与所有元素之和,我们可以转化为选择元素之和大于剩下的.然后我们可以将下标按照a从大到小排序.然后选择第一个,之后每两个一组,选择b大的一个,如果n是偶数再选择最后一个. 至于这样写

798D - Mike and distribution

题意:给n(n<=100000)组数,每组数有(a,b),求从这n组数里面选出k(k<=(n/2)+1)组.这k组所有a的和大于剩下n-k组中a的和,并且这k组中所有b的和大于剩下n-k组中b的和. 思路:首先按a排序.对于a[i],选择a[i]之前没有选择过的或者a[i]总是能>=a[i+1],然后从a[i+2]中开始选择..这样就可以保证选出来的a的和始终大于另外一半.然后对于可以选择的a,我选择最大的b,这样也可以让选出来的b有一个比它小的对应值.这个值可以通过优先队列来维护.如果

【CF 547E】 Mike and Friends

题目 显然SAM版题,写它的原因就是我太颓了:之后学习了一下正规的广义SAM写法,争取以后不再写lst=1 代码 #include<bits/stdc++.h> #define re register const int maxn=4e5+5; const int M=maxn*30; struct E{int v,nxt;}e[maxn];char S[maxn>>1]; int l[M],r[M],d[M],tot,q; int lst,cnt,n,L,num,dep[maxn

CodeForces 547E:Mike and Friends(AC自动机+DFS序+主席树)

What-The-Fatherland is a strange country! All phone numbers there are strings consisting of lowercase English letters. What is double strange that a phone number can be associated with several bears! In that country there is a rock band called CF con