Tenka1 Programmer Beginner Contest D - IntegerotS(位运算)

传送门

题意

给出N,K,给出N对数a[i],b[i],选择一些数使得or和小于k且\(max\sum b[i]\)

分析

枚举k的每一个1位,将其删去并让低位全为1,对于每一个这样的数c,如果a[i]|c==c,那么就加上b[i],最后取最大值即可

trick

代码

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))

int n, k;
int a[100100], b[100100];
ll ans, ret;
int c;
int main()
{
	cin >> n >> k;
	F(i, 1, n) scanf("%d %d", a + i, b + i);
	ans = 0;
	F(i, 1, n)
	{
		if ((a[i] | k) == k) ans += b[i];
	}
	F(i, 0, 30)if ((1 << i)&k)
	{
		c = (k - (1 << i)) | ((1 << i) - 1);
		ll ret = 0;
		F(j, 1, n) if ((c | a[j]) == c) ret += b[j];
		ans = max(ans, ret);
	}
	cout << ans << endl;
	return 0;
}
posted @ 2017-10-06 10:43  遗风忘语  阅读(123)  评论(0编辑  收藏  举报