鏈接
https://ac.nowcoder.com/acm/problem/17968
線性基
線性基的概念
在線性代數中有基的概念,我在這裏援引百度百科
異或其實就是模加法,就取,每個整數都可以看作一個向量,就取輸入的整數集合誘導出的向量集合。線性基本質上是一組基向量,只不過形式上我是用整數表示的。
線性基的構造方法
用表示最高位的在第位的向量(整數)
對於一個新加入的數(其實就是一個向量),從最高位開始掃,發現當前位(第位)等於時,如果沒有,那就令,並退出;否則^,然後繼續下一位
如果要查詢某個數能通過基中的整數異或出來,可以貪心地從高位到低位填
代碼
#include <bits/stdc++.h>
#define maxn 100010
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
struct LinearBasis
{
ll b[70];
void clear(){cl(b);}
void build(ll *a, ll len)
{
for(ll i=1;i<=len;i++)
{
ll t=a[i];
for(ll k(62);~k;k--)
if(t&(1ll<<k))
{
if(!b[k])b[k]=t;
t^=b[k];
}
}
}
bool check(ll x)
{
for(ll k(62);~k;k--)
if(x&(1ll<<k))x^=b[k];
return !x;
}
}LB;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
ll a[maxn], x, y, n;
int main()
{
ll i, q;
n=read();
for(i=1;i<=n;i++)a[i]=read();
LB.clear();
LB.build(a,n);
q=read();
while(q--)
if(LB.check(read()^read()))printf("YES\n");
else printf("NO\n");
return 0;
}