给定的阵列ARR []由N个整数的,任务是找到按位的AND的(ARR [I] + ARR [j]的)和按位与ARR [I]之和的常用3 [j]的每个对给定数组中的元素(arr[i], arr[j])。由于总和可能非常大,将其打印为模(10 9 + 7) 。
例子:
Input: arr[] = {8, 9}
Output: 0
Explanation: The only pair from the array is (8, 9). Sum of the pair = (8 + 9) = 17. Bitwise AND of the pairs = (8 & 9) = 8. Therefore required Bitwise AND = (17 & 8) = 0.
Input: arr[] = {1, 3, 3}
Output: 2
Explanation:
Pair (1, 3): Required Bitwise AND = (1 + 3) & (1 & 3) = (4 & 1) = 0.
Pair (3, 3): Required Bitwise AND = (3 + 3) & (3 & 3) = (6 & 3) = 2.
Therefore, total sum = 0 + 0 + 2 = 2.
朴素的方法:最简单的方法是从给定的数组中生成所有可能的对,并检查是否存在满足给定条件的任何这样的对。如果发现是真的,那就算这对。检查所有对后,打印结果count 。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:上述方法可以基于以下观察进行优化:
- 考虑到一对(X,Y)时,按位与在比特,说第b个是1,那么(X + Y)也必须具有第b个比特为一组位在作出贡献b个比特。
- 仅考虑这样对两个号码的最后b个比特,可以观察到,为了满足上述条件,第b个比特和(b + 1)个位,两者都将不得不被设置。
- 因此,由上述步骤可以推导出,要满足上述条件,应满足以下条件:
- 因此,任务减少以找到每个位位置满足上述条件的对的计数,并将结果增加值cnt*2 b为0 ≤ b < 31 。
请按照以下步骤解决问题:
- 初始化一个变量,比如ans ,以存储结果总和。
- 迭代范围[0, 30]并执行以下操作:
- 初始化一个向量V来存储满足上述条件的对。
- 遍历给定数组arr[]并在向量V 中插入值arr[j] – (arr[j] >> (i + 1))*(1 << (i + 1)) modulo M ,如果(( arr[j] >> (i + 1)) &1)为真。
- 按升序对向量 V 进行排序。
- 遍历向量V并执行以下操作:
- 计算值2 (i + 1) + 2 i – V[j]并将其存储在变量Y 中。
- 查找 V中大于或等于V 中Y的点数并将其存储在变量中,例如cnt,即cnt = V.size() – (lower_bound(V.begin() + j + 1, V.end (), Y) – V.begin())。
- 将ans更新为ans = (ans+ cnt* 2 i )%M 。
- 完成以上步骤后,打印ans的值作为结果。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
#define M 1000000007
using namespace std;
// Function to find the sum of Bitwise AND
// of sum of pairs and their Bitwise AND
// from a given array
void findSum(int A[], int N)
{
// Stores the total sum
long long ans = 0;
for (int i = 0; i < 30; i++) {
vector vec;
for (int j = 0; j < N; j++) {
// Check if jth bit is set
if ((A[j] >> i) & 1) {
// Stores the right shifted
// element by(i+1)
long long X = (A[j] >> (i + 1));
// Update the value
// of X
X = X * (1 << (i + 1));
X %= M;
// Push in vector vec
vec.push_back(A[j] - X);
}
}
// Sort the vector in
// ascending order
sort(vec.begin(), vec.end());
// Traverse the vector vec
for (int j = 0; j < vec.size(); j++) {
// Stores the value
// 2^(i+1)- 2^(i)- vec[j]
int Y = (1 << (i + 1))
+ (1 << i)
- vec[j];
// Stores count of numbers
// whose value > Y
int idx = lower_bound(
vec.begin() + j + 1,
vec.end(), Y)
- vec.begin();
// Update the ans
ans += (vec.size() - idx)
* 1ll * (1 << i);
ans %= M;
}
}
// Return the ans
cout << ans % M << endl;
}
// Driver Code
int main()
{
int arr[] = { 1, 3, 3 };
int N = sizeof(arr) / sizeof(arr[0]);
findSum(arr, N);
return 0;
}
Python3
# Python 3 program for the above approach
M = 1000000007
from bisect import bisect_left
# Function to find the sum of Bitwise AND
# of sum of pairs and their Bitwise AND
# from a given array
def findSum(A, N):
# Stores the total sum
ans = 0
for i in range(30):
vec = []
for j in range(N):
# Check if jth bit is set
if ((A[j] >> i) & 1):
# Stores the right shifted
# element by(i+1)
X = (A[j] >> (i + 1))
# Update the value
# of X
X = X * (1 << (i + 1))
X %= M
# Push in vector vec
vec.append(A[j] - X)
# Sort the vector in
# ascending order
vec.sort(reverse=False)
# Traverse the vector vec
for j in range(len(vec)):
# Stores the value
# 2^(i+1)- 2^(i)- vec[j]
Y = (1 << (i + 1)) + (1 << i) - vec[j]
# Stores count of numbers
# whose value > Y
temp = vec[j+1:]
idx = int(bisect_left(temp,Y))
# Update the ans
ans += ((len(vec) - idx) * (1 << i))
ans %= M
ans /= 7
# Return the ans
print(int(ans % M))
# Driver Code
if __name__ == '__main__':
arr = [1, 3, 3]
N = len(arr)
findSum(arr, N)
# This code is contributed by SURENNDRA_GANGWAR.
2
时间复杂度: O(N*log N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live