题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2844
又用到线性基+高斯消元的套路题了,因为经过高斯消元以后的线性基有非常好的序关系,所以这种套路还是经常考到的。
求出一个经过高斯消元的基以后,根据基里面的元素个数可以确定值域的数的个数,并且给定一个k也可以求出第k小的元素。那么如果把序列的元素个数比线性基的秩多出来的那些元素,其实就是把值域翻倍了。每多一个元素,值域翻两倍。B序列从0开始编号可能会容易写一点。
#include<bits/stdc++.h> using namespace std; vector<int> base; void insert(int x) { for (int i=0;i<base.size();i++) x=min(x,x^base[i]); if (x) base.push_back(x); } int main() { int n; scanf("%d",&n); for (int i=1;i<=n;i++) { int x; scanf("%d",&x); insert(x); } sort(base.begin(),base.end()); for (int i=base.size()-1;i>=0;i--) { for (int j=i+1;j<base.size();j++) { base[j]=min(base[j],base[j]^base[i]); } } int more=n-base.size(); int id=0; int q; scanf("%d",&q); for (int i=base.size()-1;i>=0;i--) { if ((q^base[i])<q) { q=q^base[i]; id^=1<<i; } } for (int i=0;i<more;i++) id=(id*2)%10086; id=(id+1)%10086; printf("%d",id); return 0; }