当前位置: 代码迷 >> 综合 >> 洛谷 P2114 [NOI2014]起床困难综合症
  详细解决方案

洛谷 P2114 [NOI2014]起床困难综合症

热度:36   发布时间:2023-12-06 07:48:09.0

题目:起床困难综合症

思路:
由于每个二进制位的位运算互不影响,所以可以把m和t都拆成二进制表示,一位一位的考虑。

代码:

#include<bits/stdc++.h>
using namespace std;#define maxn 100000
#define read(x) scanf("%d",&x)int n,m;
int opr[maxn+5],a[maxn+5];
int b[50];
int c[maxn+5][50];void cuta(int x) {
    int y=a[x],len=0;while(y) {
    c[x][++len]=y&1;y>>=1;}for(int i=1;i<=30/2;i++) swap(c[x][i],c[x][30-i+1]);
}void readin() {
    read(n),read(m);for(int i=1;i<=n;i++) {
    string op;cin>>op;opr[i]=(op[0]=='A'?1:(op[0]=='O'?2:3));read(a[i]);cuta(i);}
}void cutm() {
    int x=m,len=0;while(x) {
    b[++len]=x&1;x>>=1;}for(int i=1;i<=30/2;i++) swap(b[i],b[30-i+1]);
}int slv(int j,int y) {
    for(int i=1;i<=n;i++) {
    if(opr[i]==1) y&=c[i][j];else if(opr[i]==2) y|=c[i][j];else y^=c[i][j];}return y;
}int main() {
    readin();cutm();int ans=0,fl=0;for(int i=1;i<=30;i++) {
    int x=slv(i,0);if(b[i]==1||fl) {
    ans<<=1;if(slv(i,1)==1&&!x) ans++;else {
    ans+=x;fl=true;}} else ans<<=1,ans+=x;}printf("%d",ans);return 0;
}