AT4168 [ARC100C] Or Plus Max
从\(whk\)回来了。
考虑我们需要维护一个子集的信息。
对于二进制的子集信息维护有一个很经典的操作:
高维前缀和。
AT4168 [ARC100C] Or Plus Max
// Problem: AT4168 [ARC100C] Or Plus Max
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/AT4168
// Memory Limit: 1000 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<cstdio>
#define ll long long
#define N 1000005
struct P{
int mx1,mx2;
}f[N];
ll n;
int main(){
scanf("%lld",&n);
for(int i = 0;i <= (1 << n) - 1;++i){
ll x;
scanf("%lld",&x);
f[i].mx1 = x;
f[i].mx2 = 0;
}
for(int i = 0;i <= n - 1;++i){
for(int j = 0;j <= (1 << n) - 1;++j){
if(j & (1 << i)){
int to = j ^ (1 << i);
P k;
if(f[j].mx1 > f[to].mx1){
k.mx1 = f[j].mx1;
k.mx2 = std::max(f[to].mx1,f[j].mx2);
}
else{
k.mx1 = f[to].mx1;
k.mx2 = std::max(f[to].mx2,f[j].mx1);
}
f[j] = k;
}
}
}
ll ans = 0;
for(int i = 1;i <= (1 << n) - 1;++i)
std::cout<<(ans = std::max(ans,(ll)f[i].mx1 + f[i].mx2))<<std::endl;
}