bzoj2460元素(线性基,贪心)

Posted yimmortal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2460元素(线性基,贪心)相关的知识,希望对你有一定的参考价值。

题目大意:

给定(n)个二元组((a,b)),求一个最大的(sum b)的集合,满足这个集合的任意子集的(a)(xor)值不为0

这道题需要一个线性基的性质:
线性基的任何非空子集的(xor)值不为0

那么我们对于题目中对a的要求,只需要维护一个线性基即可。

那如何保证(sum b)最大呢....我们可以按照b排序,然后依次插入线性基,如果经过插入操作后(a[i].a)不为0,就说明他被加入了线性基,那么就可以将他的(a[i].b)加入答案

至于贪心的正确性....我也不是很会证明...大致可以理解为权值大的应该尽量早加,如果将当前点加入必须要删除之前的点的话,那一定是不优的,因为我们提前按照权值排过序

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long

using namespace std;

inline ll read()
{
  ll x=0,f=1;char ch=getchar();
  while (!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
  while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
  return x*f;
}

const int maxn = 110;

ll base[maxn],n,k;
struct Node{
    ll id,val;
};
Node a[1010];
ll ans;

bool cmp (Node a,Node b)
{
    return a.val>b.val;
}

int main()
{
  n=read();
  for (int i=1;i<=n;i++) a[i].id=read(),a[i].val=read();
  sort(a+1,a+1+n,cmp);
  for (int i=1;i<=n;i++)
  {
    for (ll j=63;j>=0;j--)
    {
        if(a[i].id & (1LL << j))
        {
            if (!base[j])
            {
                base[j]=a[i].id;
                break;
              }
            a[i].id^=base[j];
          }
      }
    if (a[i].id>0) ans+=a[i].val;
  }
  cout<<ans;
  return 0;
}

以上是关于bzoj2460元素(线性基,贪心)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2460 元素(贪心+线性基)

[bzoj2460] [BeiJing2011]元素(线性基+贪心)

bzoj 2460: [BeiJing2011]元素线性基+贪心

[bzoj 2460]线性基+贪心

BZOJ-2460&3105元素&新Nim游戏 动态维护线性基 + 贪心

BZOJ2460[BeiJing2011]元素 贪心+高斯消元求线性基