xor
xor
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
Your are given n sets.Every set contains some integers.
We say a set can express an integer, only when there exists a subset of the set such that the bitwise-xor of the elements in the subset is equal to that integer.
Now you need to answer m queries. Each query will give you three integers l,r,x and you should answer if for every i∈[l,r] ,the i-th set can express x.
We say a set can express an integer, only when there exists a subset of the set such that the bitwise-xor of the elements in the subset is equal to that integer.
Now you need to answer m queries. Each query will give you three integers l,r,x and you should answer if for every i∈[l,r] ,the i-th set can express x.
输入描述:
The first line contains two integers n,m.
For each of the following n lines, the first integer sz stands for the size of this set and the following sz integers stand for the elements in this set. The sets are described from number 1 to n.
For each of the following m lines, there're three integers l,r,x that means a query.
输出描述:
For each query, output a line.
If for every i∈[l,r] ,the i-th set can express x, you need to print “YES”, and "NO" otherwise.
输入
1 3 2 1 2 1 1 0 1 1 3 1 1 4
输出
YES YES NO
备注:
1≤n,m≤50000,1≤sz≤32,1≤l≤r≤n ,the every integer in input ∈[0,232)。
链接:https://ac.nowcoder.com/acm/contest/884/B
来源:牛客网
线性基,Mark一下线性基的交。
#include<bits/stdc++.h> using namespace std; const int Digit=60; struct L_B { long long basis[Digit+1]; L_B() { memset(basis,0,sizeof(basis)); } void operator = (const L_B & s) { for(int i=0; i<=Digit; i++)basis[i]=s.basis[i]; } bool insert(long long val) { for (int i=Digit; i>=0; i--) if (val&(1LL<<i)) { if (!basis[i]) { basis[i]=val; break; } val^=basis[i]; } return val>0; } bool check(long long val) { for (int i=Digit; i>=0; i--) if (val&(1LL<<i)) { if(basis[i])val^=basis[i]; else return 0; } return 1; } long long query_max() { long long ret=0; for (int i=Digit;i>=0;i--) if ((ret^basis[i])>ret) ret^=basis[i]; return ret; } }; L_B Merge(L_B A,L_B B) { L_B All, C, D; for (int i = Digit; i >= 0; i--) { All.basis[i] = A.basis[i]; D.basis[i] = 1ll << i; } for (int i = Digit; i >= 0; i--) { if (B.basis[i]) { long long v = B.basis[i], k = 0; bool can = true; for (int j = Digit; j >= 0; j--) { if (v & (1ll << j)) { if (All.basis[j]) { v ^= All.basis[j]; k ^= D.basis[j]; } else { can = false; All.basis[j] = v; D.basis[j] = k; break; } } } if (can) { long long v = 0; for (int j = Digit; j >= 0; j--) { if (k & (1ll << j)) { v ^= A.basis[j]; } } C.insert(v); } } } return C; } const int N = 5e4+50; struct ss { int l,r; L_B lb; }; L_B base[N]; ss tree[4*N]; void build(int v,int l,int r) { int mid=(l+r)/2; tree[v].l=l; tree[v].r=r; if(l==r) { tree[v].lb=base[l]; return; } build(2*v,l,mid); build(2*v+1,mid+1,r); tree[v].lb=Merge(tree[2*v].lb,tree[2*v+1].lb); } bool query(int v,int l,int r,int x) { // printf("%d %d %d\n",tree[v].l,tree[v].r,x); if(tree[v].l==l&&tree[v].r==r)return tree[v].lb.check(x); int mid=(tree[v].l+tree[v].r)/2; if(r<=mid)return query(2*v,l,r,x); else if(l>mid)return query(2*v+1,l,r,x); else { return query(2*v,l,mid,x)&&query(2*v+1,mid+1,r,x); } } int main() { int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) { int sz; scanf("%d",&sz); while(sz--) { int a; scanf("%d",&a); base[i].insert(a); } } build(1,1,n); while(m--) { int l,r,x; scanf("%d %d %d",&l,&r,&x); printf("%s\n",query(1,l,r,x) ? "YES" : "NO"); } return 0; }
路漫漫其修远兮,吾将上下而求索