CF1148F - Foo Fighters

CF1148F - Foo Fighters node

题意:你有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 }
AC代码
相关文章
相关标签/搜索