题目
http://codeforces.com/contest/1230/problem/D
题意
一共有n个学生
它们用从1到n的整数进行索引。每个整数都可以用两个整数ai和bi来描述;bi等于第i个学生的技能水平(越高越好)。所以,有60个已知的算法,用0到59的整数进行编号。如果第i个学生知道第j个算法,那么第j个位(2j)设置在ai的二进制表示中。否则,此位不设置。
学生x认为他比学生y好,只要x知道一些算法,而y不知道。注意,两个学生可以认为他们比对方强。如果这个小组中没有一个学生认为他比这个小组中的其他人都好,那么一群学生可以平静地一起工作。
教练希望派出至少两名学生组成的小组,他们将冷静地合作,并将拥有最大可能的技能水平总和。
题解
首先找到两个a数值完全相同的学生,把a放进set里面。
然后遍历所有学生,如果y学生的a值被x学生的a包含的话,答案就加上y学生的b。表示y的能力值被x包括表示方法(x.a | y.a == x.a)
代码
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<set>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
struct Node{
ll a;
int b;
}stu[7007];
bool cmp(Node x,Node y){
return x.a>y.a;
}
set<ll>s;
set<ll>::iterator iter;
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&stu[i].a);
for(int i=0;i<n;i++)
scanf("%d",&stu[i].b);
sort(stu,stu+n,cmp);
ll ans=0;
for(int i=0;i<n-1;i++)
{
if(stu[i].a == stu[i+1].a)
s.insert(stu[i].a);
}
for(int i=0;i<n;i++)
{
for(iter = s.begin() ; iter != s.end() ; ++iter)
{
ll temp = *iter|stu[i].a;
if(temp == *iter)
{
ans += stu[i].b;
break;
}
}
}
printf("%lld\n",ans);
return 0;
}