题面
传送门:洛谷
Solution
一道很有意思的位运算题. 要做这一题,我们首先得了解一个很重要的特点 位运算过程中每一位都不会进位 有了这个特点,我们可以考虑一个很妙的做法 我们可以把每一扇门的那个数转为2进制 就可以在$O(n)$的时间内找到这一位以1或0为初始数,过完所有门后的这位数的结果 显然,结果为1是对答案有贡献的 然后,我们从后往前,一位一位枚举看一下初始值是填1还是填0 然后就OjbK了 时间复杂度$O(logm\cdot n)$
Solution
| 12
 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;
 }
 
 |