AtCoder Regular Contest 100 (ARC100) E - Or Plus Max 其他
原文链接https://www.cnblogs.com/zhouzhendong/p/9251448.html
题目传送门 - ARC100E
题意
给定一个正整数 $n(n\leq 18)$。
然后给定一行共 $2^n$ 个正整数 $a_0,a_1,\cdots,a_{2^n-1}$ 。
对于每一个 $k(1\leq k<2^n)$ ,输出满足 $i\ OR\ j \leq k$ 的最大 $a_i+a_j$ 值。
题解
看到这题的心情:为啥不早做这题!!这题过的人怎么这么少??
连我都只想了几分钟,那么那些大佬是不是都一眼秒?
好了讲题:
考虑对于每一个 $k$ 处理出满足 $k\ OR\ x=k$ 的所有 $x$ 中 $a_x$ 最大的两个。其中 $k=0$ 的时候特殊一点注意一下。
具体怎么求???
考虑一个 $k$ 要处理的东西,可以从两个方面继承:一个是自己本身的数 $a_k$ ,另一部分是把 $k$ 的任意一个非零位换成 $0$ 得到的 $k^{\prime}$ 的结果。
然后回到原题,弄个前缀 $\max$ 就好了。
代码
#include <bits/stdc++.h> using namespace std; const int N=1<<19; int n,s,a[N]; int id[N][2]; bool cmp(int A,int B){ return a[A]<a[B]; } int main(){ scanf("%d",&n); s=1<<n; for (int i=0;i<s;i++) scanf("%d",&a[i]); a[s]=-1; id[0][0]=0,id[0][1]=s; for (int i=1;i<s;i++){ id[i][0]=i,id[i][1]=s; int x[4]; for (int j=0;j<n;j++) if (i&(1<<j)){ int _i=i^(1<<j); x[0]=id[i][0],x[1]=id[i][1]; x[2]=id[_i][0],x[3]=id[_i][1]; sort(x,x+4,cmp); id[i][0]=x[3],id[i][1]=x[2]==x[3]?x[1]:x[2]; } } int mx=0; for (int i=1;i<s;i++){ mx=max(mx,a[id[i][0]]+a[id[i][1]]); printf("%d\n",mx); } return 0; }