bzoj2460: [BeiJing2011]元素 高斯消元+贪心

本文介绍了一种利用线性基解决特定选择问题的方法。该问题要求从给定的数值对中选取若干对,使得所选对的第二项之和最大,同时这些对的第一项构成线性无关的集合。通过将数值对按第二项降序排列,并用线性基维护已选数值对第一项的线性独立性,可以高效地求解此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给n个数对(x,y),选出任意多个,使任一子集的x抑或和不为0(x线性无关)

            并使y的和最大

题解:按y从大到小加入,维护线性基,能加就加

            线性基能表示出当前集合所有子集的抑或和,故正确性显然


#include<bits/stdc++.h>
using namespace std;
#define maxn 1020
#define rep(i,l,r) for(int i = l ; i <= r ; i++)

typedef long long ll;
struct node{
	ll num;
	int val;
	bool operator < (node a)const{
		return val > a.val;
	}
}dt[maxn];
int n,ans;
ll matrix[66];

int check(ll x){
	for (int i = 60 ; i >= 0 ; i--){
		if ( (x >> i) & 1 ){
			if ( !matrix[i] ){ matrix[i] = x; break; }
			x ^= matrix[i];
		}
	}
	if ( x ) return 1;
	return 0;
}
int main(){
	scanf("%d",&n);
	for (int i = 1 ; i <= n ; i++) scanf("%lld %d",&dt[i].num,&dt[i].val);
	sort(dt + 1,dt + n + 1);
	for (int i = 1 ; i <= n ; i++){
		if ( check(dt[i].num) ) ans += dt[i].val;
	}
	cout<<ans<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值