AtCoder Regular Contest 100 - E Or Plus Max

题目描述

There is an integer sequence of length 2^N: A0,A1,…,A2^N−1. (Note that the sequence is 0-indexed.)
For every integer K satisfying 1≤K≤2^N−1, solve the following problem:
Let i and j be integers. Find the maximum value of Ai+Aj where 0≤i<j≤2^N−1 and (i or j)≤K. Here, or denotes the bitwise OR.
Constraints
1≤N≤18
1≤Ai≤10^9
All values in input are integers.

 

输入

Input is given from Standard Input in the following format:

N
A0 A1 … A2^N−1

 

输出

Print 2^N−1 lines. In the i-th line, print the answer of the problem above for K=i.

 

样例输入

2
1 2 3 1

样例输出

3
4
5

 

提示

For K=1, the only possible pair of i and j is (i,j)=(0,1), so the answer is A0+A1=1+2=3.

For K=2, the possible pairs of i and j are (i,j)=(0,1),(0,2). When (i,j)=(0,2), Ai+Aj=1+3=4. This is the maximum value, so the answer is 4.

For K=3, the possible pairs of i and j are (i,j)=(0,1),(0,2),(0,3),(1,2),(1,3),(2,3) . When (i,j)=(1,2), Ai+Aj=2+3=5. This is the maximum value, so the answer is 5.

 

题意:给2^n个数,对于每一个k(1≤K≤2^N−1),找到最大的a[i]+a[j],其中i|j<=k

思路:对于任一K1<K2,凡是满足i|j<=K1的答案一定满足i|j<=K2,所以对于每个K,只需寻找i|j=k中a[i]+a[j]的最大值。采用记录下标的形式来避免a[i]与a[j]重复。

 

#include "iostream"
#include "algorithm"
#include "set"
#include "vector"

using namespace std;
const int maxn = (1 << 18) + 100;

struct node {
    int max1, max2;
} maxx[maxn];
int s[maxn];

void fun(int a, node &b) {
    if (a == b.max2 || a == b.max1) return;
    if (s[b.max1] < s[a]) {
        swap(b.max1, b.max2);
        b.max1 = a;
    } else if (s[b.max2] < s[a]) {
        b.max2 = a;
    }
}

int main() {
    //freopen("input.txt", "r", stdin);
    int n;
    cin >> n;
    int nn = 1 << n;
    for (int i = 0; i < nn; i++) {
        cin >> s[i];
        maxx[i].max1 = i;
        maxx[i].max2 = nn;
    }
    for (int i = 1; i < nn; i++) {
        for (int j = 0; j < n; j++) {
            if (i & (1 << j)) {
                int k = i ^(1 << j);
                fun(maxx[k].max1, maxx[i]);
                fun(maxx[k].max2, maxx[i]);
            }
        }
    }
    int ans = 0;
    for (int i = 1; i < nn; i++) {
        ans = max(ans, s[maxx[i].max1] + s[maxx[i].max2]);
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2018-12-04 09:59  Albert_liu  阅读(170)  评论(0编辑  收藏  举报