BZOJ2460 线性基

来源:互联网 发布:算法工程师考试 编辑:程序博客网 时间:2024/06/06 03:02

简略题意:n个物品,每个物品两个权值。
1. 编号
2. 价值
现在需要选出若干个物品,使得他们的编号亦或和不为0,且价值最大。

线性基中任意元素的亦或值均不为0,因此只要按价值从大到小构造线性基,然后把所有的线性基对应的价值求和即可。

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 63;struct A{    LL id;    LL val;    bool operator < (const A & b) const {        return val < b.val;    }};vector<A> V;int n;LL a[maxn+1], id[maxn+1];int main() {    scanf("%d", &n);    for(int i = 1; i <= n; i++) {        LL x, y;        scanf("%lld%lld", &x, &y);        V.push_back({x, y});    }    sort(V.begin(), V.end());    for(int i = V.size() - 1; i >= 0; i--) {        for(int j = maxn; j >= 0; j--) {            if(V[i].id & (1LL << j)) {                if(a[j])                    V[i].id ^= a[j];                else {                    a[j] = V[i].id, id[j] = i;                    break;                }            }        }    }    LL ans = 0;    for(int i = maxn; i >= 0; i--)        if(a[i])            ans += V[id[i]].val;    printf("%lld\n", ans);    return 0;}
原创粉丝点击