题目大意
给定一个长度为
n
序列,
Data Constraint
n,ai≤1000000
题解
包含
ai
的数一定排在
ai
前面才优,那么最终的序列的前缀
and
必然是一堆连续的段,每段内的前缀
and
不变。
设
fi
表示
a
中有多少个数包含了
对于一个状态
至于 f 参考JZOJ4828. 最大值的分治求法。
时间复杂度:
SRC
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
#define N 2000000 + 10
typedef long long ll ;
ll g[N] ;
int a[N] , f[N] ;
int n ;
ll ans ;
void DIV( int l , int r , int w ) {
if ( l == r ) return ;
int mid = (l + r) / 2 ;
DIV( l , mid , w - 1 ) ;
DIV( mid + 1 , r , w - 1 ) ;
for (int i = l ; i <= mid ; i ++ ) f[i] += f[i+(1<<(w-1))] ;
}
int main() {
freopen( "and.in" , "r" , stdin ) ;
freopen( "and.out" , "w" , stdout ) ;
scanf( "%d" , &n ) ;
for (int i = 1 ; i <= n ; i ++ ) {
scanf( "%d" , &a[i] ) ;
f[a[i]] ++ ;
}
DIV( 0 , (1 << 20) - 1 , 20 ) ;
for (int i = (1 << 20) - 1 ; i >= 0 ; i -- ) {
for (int k = 0 ; k < 20 ; k ++ ) {
if ( (i >> k) & 1 ) continue ;
int j = i | (1 << k) ;
g[i] = max( g[i] , g[j] + 1ll * (f[i] - f[j]) * i ) ;
ans = max( ans , g[i] ) ;
}
}
printf( "%lld\n" , ans ) ;
return 0 ;
}
以上.