【JZOJ4937】【GDKOI2017模拟1.12】与运算

67 篇文章 1 订阅
5 篇文章 0 订阅

Description

这里写图片描述

Data Constraint

这里写图片描述

Solution

对于一个数x,假如存在y,使得x⊆y,那么把y放在x前面一定不会使答案变差。所以我们设g[i]表示输入中包含i的数的个数(即i是该数子集)。设f[i]表示放到i时的答案。那么显然 f[i]=max(f[i],f[j]+(g[i]g[j])i) 。( g[i]g[j] 表示那些包含i但不包含j的数量,j表示与i只有一位不同的数且j>i)。时间复杂度O( NlogN ).

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll maxn=1e3;
ll a[maxn+5],f[maxn+5],g[maxn+5],n,i,t,j,k,l,x,ans,p;
int main(){
    freopen("data.in","r",stdin);//freopen("and.out","w",stdout);
    scanf("%lld",&n);
    for (i=1;i<=n;i++)
        scanf("%lld",&x),a[x]++,g[x]++;
    for (j=0;j<=19;j++)
        for (i=maxn-(1<<j);i>=0;i--)
            if (!(i & (1<<j)))g[i]+=g[i+(1<<j)];
    for (i=maxn;i>=1;i--){  
        f[i]=i*a[i];
        for (j=0;j<20;j++){
            if ((1<<j)+i>maxn) break;
            if ((1<<j) & i) continue;
            t=i+(1<<j);
            f[i]=max(f[i],f[t]+i*(g[i]-g[t]));
        }
        ans=max(ans,f[i]);
    }
    printf("%lld\n",ans);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值