标签:exce 示例 bit insert opera amp mem return int
2 2 1 2 4 1 2 3 4 3 1 2 3 5 1 2 3 4 5Sample Output
Case #1: 1 2 3 -1 Case #2: 0 1 2 3 -1Hint
If you choose a single number, the result you get is the number you choose. Using long long instead of int because of the result may exceed 2^31-1. 题意 : 给你 n 个数 , q 个询问,每次询问第 K 异或小的值
思路分析 :线性基的板子题,构造出 n 个数的线性基,然后将每一位相互独立出来,然后看有多少个不唯一的,存在一个新的数组里,如果在新的数组中有K个元素,则异或出来的最终答案最多有 2^k ,
当然这里面是包括 0 的,但是并不是所有的都可以异或出来 0 ,那要怎么确定这个能否异或出来 0 呢?如果构造出来的线性基有 k 位不为 1,那么说明每个数都提供了 1,则说明不会异或出 0 ,否则可以。
代码示例:
#define ll long long ll n; ll a[65]; void insert(ll x){ for(ll i = 60; i >= 0; i--){ if ((1ll<<i)&x){ if (!a[i]) {a[i] = x; return;} x ^= a[i]; } } } ll cnt = 0; ll p[65]; void rbuild(){ for(ll i = 60; i >= 0; i--){ for(ll j = i-1; j >= 0; j--){ if ((1ll<<j)&a[i]) a[i] ^= a[j]; } } for(ll i = 0; i <= 60; i++){ if (a[i]) p[cnt++] = a[i]; } } ll query(ll x){ if (x >= (1ll<<cnt)) return -1; ll ans = 0; for(ll j = 60; j >= 0; j--){ if ((1ll<<j)&x){ ans ^= p[j]; } } return ans; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); ll t, q; ll x; ll kase = 1; cin >>t; while(t--){ memset(a, 0, sizeof(a)); memset(p, 0, sizeof(p)); cnt = 0; cin >> n; for(ll i = 1; i <= n; i++){ scanf("%lld", &x); insert(x); } rbuild(); cin >> q; //printf("cnt = %d\n", cnt); printf("Case #%d:\n", kase++); for(ll i = 1; i <= q; i++){ scanf("%lld", &x); if (cnt != n) x--; printf("%lld\n", query(x)); } } return 0; }
标签:exce 示例 bit insert opera amp mem return int
原文地址:https://www.cnblogs.com/ccut-ry/p/8971097.html