• Codeforces Round #618 (Div. 2) C.Anu Has a Function


    f(x,y)可以看做把 y二进制位中为1的位 对应的 x中相应位 变为0。因此第一个数以后的数顺序不影响结果。只需寻找拥有 最高独占1位 的数,将其放于第一位即可。
    f(x,y)=(x|y)y按二进制拆位发现对于第i位

    若x、y第i位均为1,函数结果第i位为0

    若x第i位为0,y第i位为1,函数结果第i位为0

    若x第i位为1,y第i位为0,函数结果第i位为1

     而对于f(f(f(f(a1,a2),a3),an1),an)无论顺序怎么排 只要第i位为1的个数≥2 n次函数运算后结果第i位为0 

    证明:

    1.若a1第i位为0 那么无论怎么排 n次函数运算后结果第i位为0

    2.若a1第i位为1 遇到第二个第i位为1的数后 函数结果第i位为0 之后就变成了第一种情况

    故最后答案只取决于第一个数,为第一个数中在n个数中只出现过一次的位

    所以为了答案最大,从高位开始贪心,只要该位只出现过一次就退出循环 因为后面位的影响之和显然没有该位大

    反思:1.对于涉及位运算且求最大值的题,一般都是从高位到低位贪心,应该果断拆位的  

               不应该仅按数的顺序来,还要根据二进制位

             2.把函数等价为了x-x&y 迭代的时候犯了煞笔错误f(f(x,y),z)=x-x&y-x&y&z了 事实上无论怎么迭代函数结果都只有两项

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    int a[N];
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int ans=0;
        for(int i=30;i>=0;i--){
            int cnt=0,pos=0;
            for(int j=1;j<=n;j++)
             if(a[j]&(1<<i)){
                 cnt++;
                 pos=j;
             }
             if(cnt==1){
             ans=pos;
             break;}
        }
        if(ans==0)for(int i=1;i<=n;i++)cout<<a[i]<<' ';
        else {
            cout<<a[ans]<<' ';
            for(int i=1;i<=n;i++)
             if(ans!=i)cout<<a[i]<<' ';
        }
        return 0;
    }
  • 相关阅读:
    ByteBuffer用法总结
    内部类访问外部同名属性或者方法
    floodlight 学习(一)
    ubuntu 更改文件所有者
    python cmd 模块
    matlab 矩阵
    python操作MySQL数据库
    Win 7 下制作 mac 系统启动U盘
    Window 常用命令
    大数据扫盲
  • 原文地址:https://www.cnblogs.com/wyh447154317/p/12289656.html
Copyright © 2020-2023  润新知