题意:
给你一个序列a,然后q个询问,每一个询问问你a中是否存在几个数异或和=x^y
解析:
线性基模板题
模板一
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;
const int MAXN = 1e5+10;
typedef long long ll;
ll a[MAXN];
int n;
struct L_B{
long long d[61],p[61];
int cnt;
L_B()
{
memset(d,0,sizeof(d));
memset(p,0,sizeof(p));
cnt=0;
}
bool insert(long long val)
{
for (int i=60;i>=0;i--)
if (val&(1LL<<i))
{
if (!d[i])
{
d[i]=val;
break;
}
val^=d[i];
}
return val>0;
}
long long query_max()
{
long long ret=0;
for (int i=60;i>=0;i--)
if ((ret^d[i])>ret)
ret^=d[i];
return ret;
}
long long query_min()
{
for (int i=0;i<=60;i++)
if (d[i])
return d[i];
return 0;
}
void rebuild()
{
for (int i=60;i>=0;i--)
for (int j=i-1;j>=0;j--)
if (d[i]&(1LL<<j))
d[i]^=d[j];
for (int i=0;i<=60;i++)
if (d[i])
p[cnt++]=d[i];
}
long long kthquery(long long k)
{
int ret=0;
if (k>=(1LL<<cnt))
return -1;
for (int i=60;i>=0;i--)
if (k&(1LL<<i))
ret^=p[i];
return ret;
}
}lb;
L_B merge(const L_B &n1,const L_B &n2)
{
L_B ret=n1;
for (int i=60;i>=0;i--)
if (n2.d[i])
ret.insert(n1.d[i]);
return ret;
}
int query(ll k) { //k是否能被a异或表示
//if(!zero&&k==0) return 0;
int w=0;
for (int j = 60; j >= 0; --j)
{
if((k>>j)&1) k=k^lb.d[j];
if(k==0) return 1;
}
return 0;
}
int main() {
#ifdef DEBUG
freopen("test.in", "r", stdin);
#endif
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&a[i]),lb.insert(a[i]);
//prepare();
int q;
scanf("%d",&q);
for(int i=0;i<q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int flag=query(x^y);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
模板二:
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;
typedef long long ll;
inline ll readLL() {
static ll n;
static int ch;
n = 0, ch = getchar();
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) n = n * 10 + ch - '0', ch = getchar();
return n;
}
const int MAX_N = 100000 + 3, MAX_BASE = 60;
int n, zero = false;
ll a[MAX_N], b[MAX_BASE + 3];
vector<ll> mmap;
void prepare() {
int cnt = 0;
memset(b, 0, sizeof b);
for (int i = 0; i < n; ++i)
for (int j = MAX_BASE; j >= 0; --j)
if (a[i] >> j & 1) {
if (b[j]) a[i] ^= b[j];
else {
b[j] = a[i], cnt++;
for (int k = j - 1; k >= 0; --k) if (b[k] && ((b[j] >> k) & 1)) b[j] ^= b[k];
for (int k = j + 1; k <= MAX_BASE; ++k) if ((b[k] >> j) & 1) b[k] ^= b[j];
break;
}
}
zero = cnt != n;
mmap.clear();
for (int i = 0; i <= MAX_BASE; ++i)
if (b[i]) mmap.push_back(b[i]);
}
int query(ll k) {
//if(!zero&&k==0) return 0;
int w=0;
for (int j = MAX_BASE; j >= 0; --j)
{
if((k>>j)&1) k=k^b[j];
if(k==0) return 1;
}
return 0;
}
int main() {
#ifdef DEBUG
freopen("test.in", "r", stdin);
#endif
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lld",&a[i]);
prepare();
int q;
scanf("%d",&q);
for(int i=0;i<q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int flag=query(x^y);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}