1. 程式人生 > >【洛谷P2114】起床困難綜合徵 位運算+貪心

【洛谷P2114】起床困難綜合徵 位運算+貪心

題目大意:給定 N 個操作,每個操作為按位與、或、異或一個固定的數字,現在要求從 0 到 M 中任選一個數字,使得依次經過 N 個操作後的值最大。

題解:位運算有一個重要的性質是:位運算時,無進位產生,每一位之間相互獨立。因此,可以從高到低依次考慮每一位對答案的貢獻值,計算每一位經過這 N 個操作後的值,比較後更新答案貢獻即可。

程式碼如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;

int n,m;
pair<string,int> a[maxn];

void read_and_parse(){
    char s[5];int val;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s%d",s,&val);
        a[i]=make_pair(s,val);
    }
}

int calc(int bit,int now){
    for(int i=1;i<=n;i++){
        int x=a[i].second>>bit&1;
        if(a[i].first=="AND")now&=x;
        else if(a[i].first=="OR")now|=x;
        else now^=x;
    }
    return now;
}

void solve(){
    int val=0,ans=0;
    for(int i=29;i>=0;i--){
        int res0=calc(i,0);
        int res1=calc(i,1);
        if(val+(1<<i)<=m&&res1>res0)ans|=res1<<i,val|=1<<i;
        else ans|=res0<<i;
    }
    printf("%d\n",ans);
}

int main(){
    read_and_parse();
    solve();
    return 0;
}