阅读 102

使用 C++ 找出与给定数组范围的异或之和最大的数字

解决一个问题,其中我们得到一个数组和一些查询。现在在每个查询中,我们都给出了一个范围。现在我们需要找到一个数字,使得它们与 x 的异或之和最大化,例如


Input : A = {20, 11, 18, 2, 13}Three queries as (L, R) pairs1 33 52 4Output : 214748362921474836452147483645


在这个问题中,由于我们已经预先计算了 1 的数量,我们现在将在每个位置的数字中取前缀计数 1,因此为了找到从 L 到 R 的给定范围内的 1 的数量,我们需要减去推定至 R 与推定至 L。

寻找解决方案的方法

在这种方法中,由于需要求最大和,所以需要使xor的大部分位等于1;因此,我们检查是否有任何位是否大于 0 的数量,因此我们重置 x 的该位,因为现在大多数数字具有该位等于 1,因此当我们将多数 1 与 0 配对时,最终我们拥有大多数该位等于 1,因此这就是我们最大化答案的方式。

示例

上述方法的 C++ 代码


#include <bits/stdc++.h>using namespace std;#define MAX 2147483647 // 2^31 - 1int prefix[100001][32]; // 前缀数组void prefix_bit(int A[], int n){ // 取 1 的前缀计数    for (int j = 0; j < 32; j++) // 我们将第 0 个计数保持为 0,我们的前缀数组从索引 1 开始        prefix[0][j] = 0;
    for (int i = 1; i <= n; i++){ // 制作我们的前缀数组        int a = A[i - 1]; // 第 i 个元素        for (int j = 0; j < 32; j++){ // 因为我们的数字小于 2^32 所以我们遍历位 0 到 31            int x = 1 << j; // 按位遍历            if (a & x) // 如果此位为 1,则我们将前缀计数为 prevcount + 1                prefix[i][j] = 1 + prefix[i - 1][j];
            else                prefix[i][j] = prefix[i - 1][j];
       }
   }
}int maximum_num(int l, int r){
    int numberofbits = r - l + 1; // 范围内的元素数,因此位数    int X = MAX; // 我们取最大值,使得它的所有位都是一    // 迭代每一位    for (int i = 0; i < 31; i++){
        int x = prefix[r][i] - prefix[l - 1][i]; // 计算给定范围内的设置位数        if (x >= numberofbits - x){ // 是 1 的数量大于 0 的数量            int currentbit = 1 << i; // 我们将当前位设置为前缀以在 x 中切换该位            X = X ^ currentbit; // 我们将那个位从 1 切换到 0        }
    }
    return X; // 回答}int main(){
    int n = 5, q = 3; // 我们数组中的元素数量和存在的查询数量    int A[] = { 210, 11, 48, 22, 133 }; // 我们数组中的元素    int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 }; // 给定查询    prefix_bit(A, n); // 创建前缀位数组    for (int i = 0; i < q; i++)
       cout << maximum_num(L[i], R[i]) << "\n";
    return 0;
}

输出结果

214748362921474836472147483629


以上代码说明

在这种方法中,我们首先计算每个位存在的 1 的前缀计数。现在,当我们得到这个计数时,我们已经解决了遍历查询的最大问题。到目前为止,我们不会遍历每个范围。所以我们现在可以通过我们的前缀数组来计算。我们的主要逻辑是,当我们遇到设置位数量大于重置位数量的位置时,我们计算范围内的重置和设置位的数量。因此,我们现在重置 x 中的那个位,因为我们已经用 2^31 - 1 初始化了 x,所以它的所有位都将被设置,我们通过切换 x 中的位来找到我们的答案。

结论

在本教程中,我们解决了一个问题,即找到与给定数组范围的异或之和最大的数字。我们还学习了针对此问题的 C++ 程序以及解决此问题的完整方法(Normal)。我们可以用其他语言编写相同的程序,例如 C、java、python 和其他语言。我们希望本教程对您有所帮助。


文章分类
百科问答
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐