F. Bits And Pieces(高妙的记忆化dp)
发布日期:2021-06-30 10:27:15 浏览次数:2 分类:技术文章

本文共 1089 字,大约阅读时间需要 3 分钟。

题意

n n n个数 a i a_i ai,找到满足 i < j < k i<j<k i<j<k的三元组最大化 a i ∣ ( a j & a k ) a_i|(a_j\& a_k) ai(aj&ak)

其中 n < 1 e 6 n<1e6 n<1e6


毫无头绪的样子…

动态维护数组 f [ m a s k ] f[mask] f[mask]表示有 f [ m a s k ] f[mask] f[mask]个数的子集是 m a s k mask mask

那么只要 f [ m a s k ] > = 2 f[mask]>=2 f[mask]>=2说明存在 a j & a k a_j\& a_k aj&ak m a s k mask mask

从后往前枚举 a i a_i ai,然后去贪心的选择 a j & a k a_j\&a_k aj&ak

具体来说从最高位往低位看,如果 a i a_i ai在当前位为零,那么就看下是否能把这一位选上

那么现在的难点是如何动态维护 f [ m a s k ] f[mask] f[mask]

如果对每个数去枚举子集的话太慢了,我们直接去从高位往低位递归所有子集

如果当前的 f [ x ] f[x] f[x]大于 2 2 2了说明不需要往下了,下面都是 x x x的子集,一定也都大于 2 2 2

否则,一直递归到底部,然后 f [ x ] + + f[x]++ f[x]++

#include 
using namespace std;const int maxn = 1<<22;int a[maxn],ans,f[maxn],n,vis[maxn];void pushdown(int x,int bit){
if( f[x]>=2 ) return; if( bit==-1 ) {
f[x]++; return; } pushdown(x,bit-1);//这一位不剥削 if( x&(1<
=0;i--) if( (x&(1<
<
=2 ) ans |= (1<
> n; for(int i=1;i<=n;i++) scanf("%d",&a[i] ); for(int i=n;i>=1;i-- ) {
if( i<=n-2 ) ans = max( ans,get( a[i] ) ); pushdown( a[i],20 ); } printf("%d",ans);}

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/112535664 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:798 D. Mike and distribution(高妙的构造+贪心)
下一篇:E. Vowels(SOSdp的简单转化)

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月24日 02时30分57秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章