題意:你有n個物品,每一個都有val和mask。c++
你要選擇一個數s,若是一個物品的mask & s含有奇數個1,就把val變成-val。ide
求一個s使得val總和變號。spa
解:分步來作。發現那個奇數個1能夠變成:每個1就變一次。code
而後把這些物品按照最高位1來分類。從0到61考慮每一類。blog
咱們試圖使每一類都與sum異號,這樣總和也異號了。get
具體來講就是看看這一類的總和,若是同號就把這以一位變成1。it
1 #include <bits/stdc++.h> 2 3 typedef long long LL; 4 const int N = 300010; 5 6 struct Node { 7 LL mask, val; 8 int id, cnt; 9 inline bool operator < (const Node &w) { 10 return mask < w.mask; 11 } 12 }node[N]; 13 14 int main() { 15 16 int n; 17 LL sum = 0; 18 scanf("%d", &n); 19 for(int i = 1; i <= n; i++) { 20 scanf("%lld%lld", &node[i].val, &node[i].mask); 21 sum += node[i].val; 22 for(int j = 0; j <= 61; j++) { 23 if((node[i].mask >> j) & 1) { 24 node[i].id = j; 25 } 26 } 27 } 28 if(sum < 0) { 29 for(int i = 1; i <= n; i++) { 30 node[i].val *= -1; 31 } 32 } 33 LL ans = 0; 34 for(int i = 0; i <= 61; i++) { 35 LL t = 0; 36 for(int j = 1; j <= n; j++) { 37 if(node[j].id != i) { 38 continue; 39 } 40 t += node[j].val; 41 } 42 if(t > 0) { 43 ans |= (1ll << i); 44 for(int j = 1; j <= n; j++) { 45 if((node[j].mask >> i) & 1) { 46 node[j].val *= -1; 47 } 48 } 49 } 50 } 51 printf("%lld\n", ans); 52 return 0; 53 }