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.
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
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; }