CF1148F - Foo Fighters

CF1148F - Foo Fighters

题意:你有n个物品,每个都有val和mask。

你要选择一个数s,如果一个物品的mask & s含有奇数个1,就把val变成-val。

求一个s使得val总和变号。

解:分步来做。发现那个奇数个1可以变成:每一个1就变一次。

然后把这些物品按照最高位1来分类。从0到61考虑每一类。

我们试图使每一类都与sum异号,这样总和也异号了。

具体来说就是看看这一类的总和,如果同号就把这以一位变成1。

 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代码

 

posted @ 2019-06-06 09:17  huyufeifei  阅读(328)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

ReadEra 阅读书籍

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜