1、UOJ 【NOI2014】起床困难综合症
参考:http://blog.csdn.net/kiana810/article/details/38226665
解题思路:
位运算各位之间的计算互不影响
所以可以按位从高到低贪心来做
贪心策略:
①在枚举前面的位数时,出现了 m 这一位上为 1 且选 0 时结果大于等于选 1 的结果,那么以后的答案的每一位就是选 0/1 的结果的最大值
②没有出现①中的情况,且 m 的这一位为 0,那么答案的这一位就是选 0 的结果
③没有出现①中的情况,且 m 的这一位为 1,如果这个时候选 0 时结果大于等于选 1 的结果,答案的这一位就是选 0 的结果,然后标记一下,以后的每一位就得都按情况①来考虑了,否则这一位就是选 1 的结果
答案的二进制的每一位已知,转换为十进制就好了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const ull INF = 0x4000000000000;
int B_m[100], _1_m[100], _0_m[100];
int ans[100];
void Operator(int n, int key);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
int n;
uint m;
scanf("%d%d", &n, &m);
char op[5];
int t;
for (int i = 0; i <= 50; ++i) {
_0_m[i] = 0;
}
for (int i = 0; i <= 50; ++i) {
_1_m[i] = 1;
}
for (int i = 0; i < n; ++i) {
scanf("%s%d", op, &t);
if (op[0] == 'A') {
Operator(t, 1);
} else if (op[0] == 'O') {
Operator(t, 2);
} else {
Operator(t, 3);
}
}
for (int i = 0; i <= 50; ++i) {
B_m[50 - i] = m % 2;
m /= 2;
}
bool flag = false;
for (int i = 0; i <= 50; ++i) {
if (flag) {
ans[i] = max(_0_m[i], _1_m[i]);
} else if (B_m[i] == 0) {
ans[i] = _0_m[i];
} else {
if (_0_m[i] >= _1_m[i]) {
flag = true;
ans[i] = _0_m[i];
} else {
ans[i] = _1_m[i];
}
}
}
ull ans_last = 0;
ull key_t = INF;
for (int i = 0; i <= 50; ++i) {
ans_last += key_t*ans[i];
key_t >>= 1;
}
printf("%llu\n", ans_last);
return 0;
}
void Operator(int n, int key)
{
for (int i = 0; i <= 50; ++i) {
int t = n%2;
if (key == 1) {
_0_m[50 - i] &= t;
_1_m[50 - i] &= t;
} else if (key == 2) {
_0_m[50 - i] |= t;
_1_m[50 - i] |= t;
} else {
_0_m[50 - i] ^= t;
_1_m[50 - i] ^= t;
}
n /= 2;
}
}
2、HDU 5745 La Vie en rose
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int n, m;
char s[maxn], p[6000];
bitset<maxn> bs[3], w[26];
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
scanf("%s%s", s, p);
for (int i = 0; i < 3; ++i) {
bs[i].reset();
}
for (int i = 0; i < 26; ++i) {
w[i].reset();
}
for (int i = 0; i < n; ++i) {
w[s[i]-'a'][i] = 1;
bs[0][i] = 1;
}
for (int i = 0; i < m; ++i) {
int t1 = p[i] - 'a';
bs[(i+1)%3] = bs[i%3] & (w[t1] >> i);
if (i > 0) {
int t2 = p[i-1] - 'a';
bs[(i+1)%3] |= bs[(i+2)%3] & (w[t2] >> i) & (w[t1] >> (i-1));
}
}
for (int i = 0; i < n; ++i) {
if (bs[m%3][i] == 1) {
printf("1");
} else {
printf("0");
}
}
printf("\n");
}
return 0;
}
3、HDU 5969 最大的位或
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef unsigned long long ull;
int T;
ull l, r;
int key1[100], key2[100];
bool vis[100];
int main()
{
#ifdef Floyd
freopen("in.txt", "r", stdin);
#endif // Floyd
scanf("%d", &T);
while (T--) {
memset(vis, false, sizeof(vis));
scanf("%lld %lld", &l, &r);
ull ans = r;
int cnt1 = 0;
while (r) {
int t = r % 2;
key1[cnt1++] = t;
r /= 2;
}
ull l_t = ((ull)1 << (cnt1 - 1)) - 1;
if (l_t >= l) {
ans = ((ull)1 << cnt1) - 1;
} else {
while (1) {
key2[cnt1 - 1] = 1;
for (int i = cnt1 - 2; i >= 0; --i) {
key2[i] = key1[i];
if (key1[i] == 1 && !vis[i]) {
vis[i] = true;
key2[i] = 0;
for (int j = i - 1; j >= 0; --j) {
key2[j] = 1;
}
break;
}
}
ull ans_t = 0;
for (int i = 0; i < cnt1; ++i) {
ans_t += ((ull)1 << i) * key2[i];
}
if (ans_t >= l) {
ans |= ans_t;
break;
}
}
}
printf("%llu\n", ans);
}
return 0;
}