题解 | #位域之中#

位域之中

https://ac.nowcoder.com/acm/contest/66846/J


存在长度为 n 的a1,,an
      和长度为m 的b1....bm
   |   运算  : 1000|0110=1110   ,即:   保留所有的1    
   ^  运算:1110^1000=0110  , 即:一样为1的位变为0,其他位有1为1
由于位运算是针对数字的二进制下的每一位单独的运算,所以我们单独抽出数字b中某一位进行模拟,可以得出以下规律:

①当数字b的第 t 位为1时:
         则进行对所有a1~an进行ai=ai∣b 的操作时
         a1~an的每个数字的第 t 位都会变成1
        则x的第t位只取决于 n的奇偶性
        当n%2==1时:
                        x的第 t 位为1
         当n%2==0时:
                         x的第t 位为 0 


②当数字b的第 t 位为0 时:
          则进行对所有a1~an进行ai=ai∣b 的操作时
          a1~an的每个数字的第 t 位都不变
          则对于x的第t位无影响



综上我们可以发现:只有b中的1可以影响x的值,同时  ③当n为偶数时,每次进行操作都会使x中的0增多或不变,即 : 使x减小或不变
                                                                                         当n为奇数时,每次进行操作都会使x中的1增多或不变,即 : 使x增大或不变

所以我们可以很快得出结论,当n为偶数时:x_max=a1^a2^a3,,,,^an
                                              当n为奇数时:x_min=a1^a2^a3,,,,^an


 要求    n为奇数时的最大值    和  n为偶数时的最小值    则 由结论③的出,要对a1..an进行最多次的操作  即要使b1,,,bm都进行ai=ai∣b 的操作     

由于 |  是保留所有的1 的操作,所以 算得  b_max=b1|b2|...|bm   来获取最后能够通过操作得到的最多的  1

则  当n为奇数时:x_max=x|b_max     ( x=a1^a2^a3,,,,^an)
当n为偶数时:由于b_max的操作使得b_max中为1的位  在x中为0,而b_max中为0的位,在x中不发生改变
所以可以得到   当n为偶数时:x_min=x&(~b_max)    

python3
time=int(input())
for i in range(time):
    [n,m]=[int(i) for i in input().split()]
    a_list=[int(i) for i in input().split()]
    b_list=[int(i) for i in input().split()]
    x1=a_list[0]
    bm=b_list[0]
    for i in a_list[1:]:  #得到x
        x1=x1^i 

    for i in b_list[1:]:#得到b_max
        bm=bm|i 
    if n%2==1:       #奇偶类型分类
        x_min=x1
        x_max=x1|bm
    elif n%2==0:
        x_max=x1
        x_min=x1 & (~bm)
    print(x_min,x_max)



这不是我写的但思想应该差不多吧

c++
#include<bits/stdc++.h>
using namespace std;
int a[200050],b[200050];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        int ans1=0;
        for(int i=1;i<=n;i++){cin>>a[i];ans1^=a[i];}
        for(int i=1;i<=m;i++)
        {
            cin>>b[i];
            b[i]|=b[i-1];
        }
        for(int i=1;i<=n;i++){a[i]|=b[m];}
        int ans2=0;
        for(int i=1;i<=n;i++){ans2^=a[i];}
        cout<<min(ans1,ans2)<<" "<<max(ans1,ans2)<<endl;
    }
}







































全部评论

相关推荐

已注销:再接着投吧项目经历太流水账,且没有实习经历,我之前也是这样,后来跟着大厂导师修改了项目和简历之后成功上岸,有需要可以问我
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
06-21 11:33
昨天是学校最后一场招聘会,鼠鼠去参加了,全场只有一个招聘java的岗位,上来先做一份笔试题,做完后他拿张纸对答案,然后开始问简历上的问题,深圳小厂,6-8k(题目如下),后面还有两轮面试。然后我就在招聘现场逛呀逛,看到有公司招聘电商运营,给的比上年的小厂还多,鼠鼠就去了解了下,然后hr跟鼠鼠要了份简历,虽然我的简历上面全是求职Java开发相关的内容,但是hr还是鼓励我说没关系,她帮我把简历给老板看看,下周一会给我通知。招聘会结束后鼠鼠想了一段时间,也和朋友聊了聊,发现我可能是不太适合这个方向,然后就跟爸爸说回家了给我发条微信,我有些话想跟他说说。晚上爸爸到家了,跟我发了条微信,我立马跑出图书馆跟他打起了电话,这个通话长达一个小时,主要是跟爸爸坦白说我不想找这行了,是你的儿子太没用了,想试试其他行业。然后爸爸也跟我说了很多,说他从来没有希望我毕业后就赚大钱的想法,找不到就回家去,回家了再慢慢找,实在找不到就跟他干(帮别人装修房子,个体户),他也知道工作不好找,让我不要那么焦虑,然后就是聊一些家常琐事。对于后面的求职者呢我有点建议想提一下,就是如果招实习的时间或者秋招开始,而你的简历又很差的情况下,不要说等做好项目填充完简历之后再投,那样就太晚了,建议先把熟悉的项目写上简历,然后边投边面边完善,求职是一个人进步的过程,本来就比别人慢,等到一切都准备好后再投岂不是黄花菜都凉了。时间够的话还是建议敲一遍代码,因为那样能让你加深一下对项目的理解,上面那些说法只是针对时间不够的情况。当然,这些建议可能没啥用,因为我只是一个loser,这些全是建立在我理想的情况下,有没有用还需其他人现身说法。上篇帖子没想到学校被人认了出来,为了不丢脸只能匿名处理了。
KPLACE:找研发类或技术类,主要还是要1.多投 2.多做准备,很多方面都要做准备 3.要有心理准备,投累了就休息一两天,再继续,要相信自己能找到
投递58到家等公司10个岗位
点赞 评论 收藏
分享
07-31 14:17
门头沟学院 Java
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务