bzoj 2460: [BeiJing2011]元素
线性基%%%%(说的那么玄乎,就是数学学的基底(只不过垃圾高中数学只学了2,3维,那么扩充到n维是一样的))
对于线性基的构造:
因为给出一个数列,由这个数列可以构造出来的数,肯定可以由线性基构造出来,且数都一样。
为什么呢?因为线性基正是由原来的这些数构造出来的,而且我们构造每个数最高位(二进制)都不相同,即这些数就包含了所有能出现二进制位。
因为这些个数是由原数xor出来的,肯定是能xor回去的(2333,我太弱,只能这样证明)
可以证明的是,线性基的真子集是不会出现0的。
然后,对于最大值的构造,以及这个题什么最大和(这个题最大和是用的贪心策略,证明不会,看神犇说用拟阵(不想看))都拿着线性基是使劲往最高位上加1就好了
(1LL<<i)(不带LL就错,真坑爹)
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline LL ra() 7 { 8 LL x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 LL p[100]; 14 struct node{LL val;LL num;}a[N]; 15 bool cmp(node a, node b){return a.val>b.val;} 16 int main() 17 { 18 LL n=(int)ra(); LL ans=0; 19 for (int i=1; i<=n; i++) 20 a[i].num=ra(),a[i].val=(int)ra(); 21 sort(a+1,a+n+1,cmp); 22 for (int i=1; i<=n; i++) 23 { 24 for (int j=65; j>=0; j--) 25 if ((1LL<<j)&a[i].num) 26 { 27 if (!p[j]) {p[j]=a[i].num; break;} 28 else a[i].num^=p[j]; 29 } 30 if (a[i].num) ans+=a[i].val; 31 } 32 cout<<ans; 33 return 0; 34 }