貪心+位運算 NOI2014 起床困難綜合徵
阿新 • • 發佈:2018-11-08
題意:
你可以任意選擇一個
的數,有
次操作,有n次操作,對於每次操作有三種情況:分別為&一個數,|一個數,和^一個數,求n次操作後最大能得到多少。
題解:
直接做並不好做,暴力列舉選哪個數的話很難進一步優化了。
這道題我們像很多位運算有關題目一樣按位考慮,因為每一個二進位制位之間互不影響。我們把數拆成二進位制數,從高位到低位考慮,我們列舉答案的每一位,因為越靠前的位為
答案越大。首先對於當前的情況,如果此時列舉到的這位為
的話,答案已經超過
,即ans+(1<<i)>m時,就continue掉,否則將這位為
和這位為
所得到的答案通過
次操作,看得到的答案哪個更大,來決定這一位填
還是填
。
#include<bits/stdc++.h>
using namespace std;
int n,m,opt[1001000],t[1001000],ans;
char s[10000];
int calc(int x)
{
for(int i=1;i<=n;++i)
{
if(opt[i]==1)
x&=t[i];
else if(opt[i]==2)
x|=t[i];
else
x^=t[i];
}
return x;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;++i)
{
scanf("%s%d",s+1,&t[i]);
if(s[1]=='A')
opt[i]=1;
else if(s[1]=='O')
opt[i]=2;
else
opt[i]=3;
}
for(int i=31;i>=0;--i)
{
if(ans+(1<<i)>m)
continue;
else if(calc(ans+(1<<i))>calc(ans))
ans+=(1<<i);
}
cout<<calc(ans);
return 0;
}