首页 > 代码库 > bzoj3668 [Noi2014]起床困难综合症

bzoj3668 [Noi2014]起床困难综合症

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3668

【题解】

我们枚举每位选啥即可。如果选0就能使最后变成1,显然选0,如果选1还不能使最后变成1,那么选0,否则选1.

日哦。。2^31刚好爆int

技术分享
# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

int n, m;
struct pa {
    int op, x;
    pa() {}
    pa(int op, int x) : op(op), x(x) {}
} p[M];
char str[5];

int main() {
    scanf("%d%d", &n, &m);
    for (int i=1, x; i<=n; ++i) {
        scanf("%s%d", str, &x);
        if(!strcmp(str, "AND")) p[i] = pa(1, x);
        if(!strcmp(str, "OR")) p[i] = pa(2, x);
        if(!strcmp(str, "XOR")) p[i] = pa(3, x);
    }
    int cur = 0, ans = 0;
    # define g ((p[j].x>>i)&1)
    for (int i=30; ~i; --i) {
        int a = 0;
        for (int j=1; j<=n; ++j) {
            if(p[j].op==1) a = a & g;
            if(p[j].op==2) a = a | g;
            if(p[j].op==3) a = a ^ g;
        }
        if(a) continue;
        a = 1;
        for (int j=1; j<=n; ++j) {
            if(p[j].op==1) a = a & g;
            if(p[j].op==2) a = a | g;
            if(p[j].op==3) a = a ^ g;
        }
        if(a && (ans+(1<<i)) <= m) ans = ans + (1<<i);
    }
    for (int j=1; j<=n; ++j) {
        if(p[j].op==1) ans = ans & p[j].x;
        if(p[j].op==2) ans = ans | p[j].x;
        if(p[j].op==3) ans = ans ^ p[j].x;
    }
    # undef g
    printf("%d\n", ans);        
    return 0;
}
View Code

 

bzoj3668 [Noi2014]起床困难综合症