线性基 P4570 [BJWC2011]元素
线性基裸题,虽然说是比较裸的题目,但是呢,我才开始学这个,还不知道线性基到底是做什么的,只知道它和异或有关系,可以求出一个序列的异或值最大,异或值最小和异或值第k大。
这个题目呢有一点点贪心,首先要贪心的考虑取最大值,然后判断能不能放进去,后面的数字能放进去就放进去,不能放进去就算了,因为不能放进去,如果硬要放进去,那么就会把前面的删掉,这样是不对的。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
long long d[maxn],num[maxn],w[maxn],ans,flag[maxn];
void add(int x) {
ll maxs = 0, pos = 0, now = num[x];
for (int i = 60; i >= 0; i--) {
if (now & (1ll << i)) {
if (d[i]) {
now ^= d[i];
} else {
maxs = w[x], pos = i, d[i] = now;
break;//插入成功就退出
}
}
}
ans += maxs;
flag[pos] = x;
}
int p[maxn];
bool cmp(int i,int j){
return w[i]>w[j];
}
int main(){
int n;
ans = 0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&num[i],&w[i]);
p[i]=i;
}
sort(p+1,p+1+n,cmp);
for(int i=1;i<=n;i++) add(p[i]);
printf("%lld\n",ans);
return 0;
}
/*
4
2 1
4 9
7 2
3 4
4
2 9
4 8
7 7
3 6
2 10
4 100
7 111
3 11
*/