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;
}
原文地址:https://www.cnblogs.com/dixiao/p/14985698.html