Codeforces Round #618 (Div. 1)-----A. Anu Has a Function

这篇文章介绍了如何解决Codeforces Round #618 (Div.1)中的A.Anu Has a Function问题,通过二进制操作理解f(x,y)的性质,利用位运算技巧求解最优序列重排,关键在于找到最大f(...)*a[n]的元素位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:
Codeforces Round #618 (Div. 1)-----A. Anu Has a Function

题意:

  • 定义一个函数f(x , y) = f(x | y) - y
  • 给定一个长度为n的序列a,给序列重新排序,使得f(f…f(f(a1,a2),a3),…an−1​),an)的值最大
  • n(1≤n≤10^5), ai(0≤ai≤10^9)

解题思路:


上图是计算f(11,6)的过程,可以发现运算结果对于 “11” 的二进制表示就是如果该位在"6"的二进制表示中对应的值是1那么这位就是0,否则不变,然后我们就可以得出f(x,y) = (x | y) - y = x & (~y)

由题中所要求的f(f…f(f(a1,a2),a3),…an−1​),an)化简为a1 & (~a2) & (~a3) & (~a4) & … & (~an),要使得这个式子最大,只需要找到一个a1和剩余的式子与最大就ok,假设a1为数组中的第k个,则
在这里插入图片描述
最后记录令函数值最大的k,最后a1与ak交换输出序列就ok,时间复杂度为O(n)

解题代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N = 1e5 + 10;
int n, k, mx = -0x3f3f3f3f, tp;
int sum1[N], sum2[N], a[N];

int main()
{
    scanf("%d",&n);
    for(int i = 1 ; i <= n ; ++i)
    {
        scanf("%d",&a[i]);
        sum1[i] = sum1[i-1] | a[i];
    }
    for(int i = n ; i >= 1 ; --i)
        sum2[i] = sum2[i+1] | a[i];
    for(int i = 1 ; i <= n ; ++i)
        if((tp = a[i] & ~(sum1[i-1] | sum2[i+1])) > mx)
            mx = tp, k = i;
    printf("%d",a[k]);
    for(int i = 1 ; i <= n ; ++i)
        if(i != k)
            printf(" %d",a[i]);
    printf("\n");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值