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

Posted wyh447154317

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #618 (Div. 2) C.Anu Has a Function相关的知识,希望对你有一定的参考价值。


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;
}

 

以上是关于Codeforces Round #618 (Div. 2) C.Anu Has a Function的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #618 (Div. 2)

Codeforces Round #618 (Div. 2)

Codeforces Round #618 (Div. 2)

Codeforces Round #618 (Div. 2)题解

Codeforces Round #618 (Div. 2)题解

Codeforces Round #618 (div 1)做题记录