zoukankan      html  css  js  c++  java
  • [P2114] [NOI2014]起床困难综合症 (位运算)

    题面

    传送门:https://www.luogu.org/problemnew/show/P2114


    Solution

    一道很有意思的位运算题.

    要做这一题,我们首先得了解一个很重要的特点

    位运算过程中每一位都不会进位

    有了这个特点,我们可以考虑一个很妙的做法

    我们可以把每一扇门的那个数转为2进制

    就可以在O(n) 的时间内找到这一位以1或0为初始数,过完所有门后的这位数的结果

    显然,结果为1是对答案有贡献的

    然后,我们从后往前,一位一位枚举看一下初始值是填1还是填0

    然后就OjbK了

    时间复杂度O(logm*n)


     Solution

    //Luogu P2114 [NOI2014]起床困难综合症
    //May,26th,2018
    //位运算拆分法
    #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;
    }
    正解(c++)
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    putty设置用key自动登录
    linux快速进入全屏命令行模式
    二维数组的指针
    vim编写Bash脚本
    使用cat命令添加或附加多行文本
    Linode中的Network Helper
    网络通信框架之retrofit
    网络通信框架之okHttp
    网络通信框架之okHttpUtils
    Volley源码分析
  • 原文地址:https://www.cnblogs.com/GoldenPotato/p/9097453.html
Copyright © 2011-2022 走看看