【线性基】[BJWC2011]元素题解

题目链接

BJWC2011元素

题目描述

给出 n n n对数字,每对第一个为 n u m num num,每对第二个为 v a l val val,求在若干个 n u m num num异或和不为 0 0 0的时候的 v a l val val的最大值。

题目思路

我们对每对数据的val进行排序,然后插入每个的 n u m num num,如果能插入就加上此时的 v a l val val,这运用了贪心的思想。

为什么呢?我一开始也提问,如果有 a , b , c , d , e a,b,c,d,e a,b,c,d,e多组数据按照 v a l val val依次递减,有没有可能不选 a a a呢?(因为 a a a n u m num num是第一个插入的,必定选)

你认为 b b b c c c在一起搭配 v a l val val可能比a的大,错了,那么我 a a a b b b肯定更大,这样可能不能理解,那么我们这样看:假如 a , b , c a,b,c a,b,c n u m num num异或和为 0 0 0,说明不能同时取,这是和最优解肯定是 a , b a,b a,b一起然后不选 c c c,这时候我们找下面的d,e,这样的话有两种情况:1)如果d ^ e = c的话我们只能选其中一个,不然a ^ b ^ d ^ e = 0,那我们肯定选d;2)如果d ^ e != c那么我们都可以选。

能不能选a的问题还是没有解决,假如我选了 b , c b,c b,c不选 a a a,此时也是两种情况,一种只能选一个,一种多选,那么我肯定选择 a a a而不是选择 c c c,因为 a . v a l ≥ c . v a l a.val \geq c.val a.valc.val,所以这种贪心是正确的。

代码

ll p[N],x,ans,d[N],cnt,flag;
int n,m;
struct node
{
    ll num,val;
}a[N];
inline bool insert(ll x)
{
    for (int i=62;i>=0;i--)
        if (x>>i)
            if (p[i])
                x^=p[i];
            else
            {
                p[i]=x;
                return 1;//插入成功
            }
    return 0; //插入失败
}
bool cmp(node x,node y)
{
    return x.val>y.val;
}
inline void Case_Test()
{
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i].num>>a[i].val;
    sort(a+1,a+1+n,cmp);
    for (int i=1;i<=n;i++)
        if (insert(a[i].num))//插入成功
            ans+=a[i].val;
    cout<<ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值