链接:

https://codeforces.com/contest/1230/problem/D

题意:

Marcin is a coach in his university. There are n students who want to attend a training camp. Marcin is a smart coach, so he wants to send only the students that can work calmly with each other.

Let's focus on the students. They are indexed with integers from 1 to n. Each of them can be described with two integers ai and bi; bi is equal to the skill level of the i-th student (the higher, the better). Also, there are 60 known algorithms, which are numbered with integers from 0 to 59. If the i-th student knows the j-th algorithm, then the j-th bit (2j) is set in the binary representation of ai. Otherwise, this bit is not set.

Student x thinks that he is better than student y if and only if x knows some algorithm which y doesn't know. Note that two students can think that they are better than each other. A group of students can work together calmly if no student in this group thinks that he is better than everyone else in this group.

Marcin wants to send a group of at least two students which will work together calmly and will have the maximum possible sum of the skill levels. What is this sum?

思路:

由题意可得, 组合内必须有两个相同的, 考虑所有拥有两个或两个以上相同a的集合.

这些集合可以组成一个大集合.同时其他值只要不存在有这些集合共有的值即可.

判定过程使用位运算可以优化到O(n)(没试过)

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 7e3+10; struct Node
{
LL a, b;
}node[MAXN];
map<LL, pair<int, LL> > Mp;
LL Id[MAXN], Val[MAXN];
int n, cnt = 0; bool Check(LL a, LL b)
{
while (b)
{
if (((a&1) == 0) && ((b&1) == 1))
return false;
a >>= 1;
b >>= 1;
}
return true;
} int main()
{
cin >> n;
for (int i = 1;i <= n;i++)
cin >> node[i].a;
for (int i = 1;i <= n;i++)
cin >> node[i].b;
for (int i = 1;i <= n;i++)
{
Mp[node[i].a].first++;
Mp[node[i].a].second += node[i].b;
}
LL maxa = 0, maxb = 0;
for (auto x:Mp)
{
if (x.second.first > 1)
{
Id[++cnt] = x.first;
Val[cnt] = x.second.second;
}
}
if (cnt == 0)
{
puts("0");
return 0;
}
LL res = 0;
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= cnt;j++)
{
if (node[i].a == Id[j])
break;
if (Check(Id[j], node[i].a))
{
res += node[i].b;
break;
}
}
}
for (int i = 1;i <= cnt;i++)
res += Val[i];
cout << res << endl; return 0;
}

最新文章

  1. UML类图的6大关系
  2. 大理石在哪里UVa 10474
  3. hadoop运维经验
  4. JsonView Tool
  5. 快速设置超炫banner,js插件
  6. 51NOD 算法马拉松12
  7. Android开发--Activity的创建
  8. USB2.0的基本学习
  9. openstack私有云布署实践【16.3 Windows Server2008 R2 只有C盘分区镜像制作】
  10. JS+CSS实现的下拉刷新/上拉加载插件
  11. Codeforces 376B. Coupons and Discounts
  12. 【Spark篇】---Spark中资源和任务调度源码分析与资源配置参数应用
  13. Java开发知识之Java中的集合Set接口以及子类应用
  14. 【托业】【怪兽】TEST01
  15. 理解PeopleSoft集成代理(Integration Broker)-第1部分
  16. Python_生成器函数进阶_39
  17. vue项目从引入vue.js 改为使用vue-cil (webpack)时修改的一些内容
  18. Cron 表达式
  19. CPP_异常处理
  20. 三、Linux学习之命令基本格式篇

热门文章

  1. Linux基础指令--文件操作
  2. php源码安装执行configure报错error: off_t undefined; check your library configuration
  3. 一个MySQL JDBC驱动bug引起的血案
  4. 并不对劲的CF1245E&amp;F:Cleaning Ladders
  5. Core项目部署到IIS上delete、put谓词不支持
  6. IE各版本处理XML的方式
  7. Web API与MVC控制器的区别
  8. redis 命令行操作报错
  9. 【Android】笔记
  10. 本地存储和vuex使用对比