NC18979 毒瘤xor

毒瘤xor

https://ac.nowcoder.com/acm/problem/18979

题目要求图片说明 最大,涉及到异或操作,很显然我们需要用位运算来处理这题

思路:
位运算时,每一个bit可以被独立的拿出来运算,所以我们记X的第p位bit为图片说明 ,区间里图片说明 的第p位bit为图片说明看看怎么让区间里图片说明 最大,也就是让区间里第p位bit上出现1的次数最多
二进制中每一个bit不是0就是1,我们又知道异或运算图片说明图片说明图片说明 ,想让一个bit变成1,那么参与运算的两个bit必须是一个0和一个1,区间里图片说明都是固定的,所以我们需要改变图片说明
结合题目说明 “若有多组可行解,请输出较小的解”
这样我们就可以推断出:

  • 当区间里第p位上1的数量大于0时,令图片说明
  • 当区间里第p位上1的数量等于0时,令图片说明 ,(输出较小的解)
  • 当区间里第p位上1的数量小于0时,令图片说明

这样对每一个图片说明处理完以后,就得到了符合题意的图片说明

当然,如果每一次询问都数一下出现了多少次1的话计算量 可能 有点大,所以下面用了前缀和

*把DEBUG改成1会输出nums和bit

#include <iostream>
#include <memory.h>
#include <algorithm>

#define DEBUG 0
using namespace std;

int main() {
    int N;  //序列长度
    cin >> N;
    int nums[N + 1];  //a1~aN
    int bit[N + 1][33];   //a1~aN的二进制各个位中1出现的次数(从右往左数)
    memset(nums, 0, sizeof(nums));
    memset(bit, 0, sizeof(bit));
    for (int i = 1; i <= N; ++i) {
        cin >> nums[i];
        for (int j = 0; j <= 31; ++j) {
            bit[i][j + 1] = bit[i - 1][j + 1];
            if (nums[i] & (1 << j))bit[i][j + 1]++;
        }
    }
    //输出nums
    if (DEBUG) {
        cout << "nums: ";
        for (int i = 1; i <= N; ++i) {
            cout << nums[i] << " ";
        }
        cout << endl;
    }
    //输出bit
    if (DEBUG) {
        cout << "bit: " << endl;
        for (int i = 0; i <= N; ++i) {
            cout << "[" << i << "]: ";
            for (int j = 32; j >= 1; --j) {
                cout << bit[i][j] << " ";
            }
            cout << "( " << nums[i] << " )" << endl;
        }
        cout << endl;
    }

    int q;  //询问的次数
    cin >> q;
    for (int i = 0; i < q; ++i) {
        int L, R;    //区间端点(闭区间)
        cin >> L >> R;
        int X = 0;    //解
        for (int j = 31; j >= 1; --j) {
            if (bit[R][j] - bit[L - 1][j] < (R - L + 1) / 2.0) {
                X += (1 << (j - 1));
            }
        }
        cout << X << endl;
    }
}
全部评论

相关推荐

HR_丸山彩同学:你的项目描述里,系统设计讲了很多:MemCube是什么、三级存储架构怎么设计、四种遗忘策略分别是什么。这些面试的时候讲没问题,但简历上不需要这么细。 简历要突出的是影响力,不是实现细节。面试官看简历的时候想知道的是「这个项目有多大价值」,不是「这个项目具体怎么实现的」。实现细节是面试时候聊的 怎么改:技术细节可以精简为一句「采用三级存储架构+四种遗忘策略」,把省出来的篇幅用来写影响力。比如:项目有没有开源?有没有写成技术博客?有没有被别人使用过? 校园经历没有任何信息量,任何人都可以写这句话,写了等于没写。更关键的是,你投的是技术岗,校园活动经历本来就不是加分项。如果非要写,必须写出具体的数字和成果。如果你没有这些数字,那就老老实实删掉 「端到端耗时缩减30-40%」要给出确切数字和绝对值。从1000ms降到600ms是降了40%,从100ms降到60ms也是降了40%,但这两个含义完全不一样。其他也是,涉及到数据,准备好证据,口径统一,面试会问 「熟练」「熟悉」「了解」混在一起用,读起来很乱。而且「了解前端需求」最好改成「具备前后端协作经验」
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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