题面
传送门:洛谷
Solution
一道很有意思的位运算题. 要做这一题,我们首先得了解一个很重要的特点 位运算过程中每一位都不会进位 有了这个特点,我们可以考虑一个很妙的做法 我们可以把每一扇门的那个数转为2进制 就可以在$O(n)$的时间内找到这一位以1或0为初始数,过完所有门后的这位数的结果 显然,结果为1是对答案有贡献的 然后,我们从后往前,一位一位枚举看一下初始值是填1还是填0 然后就OjbK了 时间复杂度$O(logm\cdot n)$
Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include<iostream> #include<cstdio> using namespace std; long long read() { long long x=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } const int N=100000+1000; const int LEN=35; struct OP { int a[LEN],type; }op[N]; long long n,m; int Count(int x,int p) { for(int i=1;i<=n;i++) { if(op[i].type==1) x=x & op[i].a[p]; else if(op[i].type==2) x=x op[i].a[p]; else x=x ^ op[i].a[p]; } return x; } int main() { n=read(),m=read(); char temp[5]; for(int i=1;i<=n;i++) { scanf("%s",temp+1); if(temp[1]=='A') op[i].type=1; else if(temp[1]=='O') op[i].type=2; else op[i].type=3; int t_num=read(); for(int j=0;t_num!=0;j++) { op[i].a[j]=t_num%2; t_num/=2; } }
long long used=0,ans=0; for(int i=0;i<=30;i++) { int temp=Count(0,i); if(temp==1) { ans+=(1<<i); continue; } temp=Count(1,i); if(temp==1 and used+(1<<i) <=m) { ans+=(1<<i); used+=(1<<i); } }
printf("%lld",ans); return 0; }
|