给定数组arr []和整数K ,任务是计算按位OR≥K的子数组的数量。
例子:
Input: arr[] = { 1, 2, 3 } K = 3
Output: 4
Bitwise OR of sub-arrays:
{ 1 } = 1
{ 1, 2 } = 3
{ 1, 2, 3 } = 3
{ 2 } = 2
{ 2, 3 } = 3
{ 3 } = 3
4 sub-arrays have bitwise OR ≥ K
Input: arr[] = { 3, 4, 5 } K = 6
Output: 2
天真的方法:运行三个嵌套循环。最外面的循环确定子数组的开始。中间循环确定子数组的结尾。最内层的循环遍历子数组,其边界由最外层和中间的循环确定。对于每个子数组,计算OR,如果OR大于K ,则更新count = count + 1 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the count of required sub-arrays
int countSubArrays(const int* arr, int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int bitwise_or = 0;
// Traverse sub-array [i..j]
for (int k = i; k <= j; k++) {
bitwise_or = bitwise_or | arr[k];
}
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
int main()
{
int arr[] = { 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 6;
cout << countSubArrays(arr, n, k);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class solution
{
// Function to return the count of required sub-arrays
static int countSubArrays(int arr[], int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int bitwise_or = 0;
// Traverse sub-array [i..j]
for (int k = i; k <= j; k++) {
bitwise_or = bitwise_or | arr[k];
}
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
public static void main(String args[])
{
int arr[] = { 3, 4, 5 };
int n = arr.length;
int k = 6;
System.out.println(countSubArrays(arr, n, k));
}
}
// This code is contributed by
// Surendra_Gangwar
Python3
# Python3 implementation of the approach
# Function to return the count of
# required sub-arrays
def countSubArrays(arr, n, K) :
count = 0;
for i in range(n) :
for j in range(i, n) :
bitwise_or = 0
# Traverse sub-array [i..j]
for k in range(i, j + 1) :
bitwise_or = bitwise_or | arr[k]
if (bitwise_or >= K) :
count += 1
return count
# Driver code
if __name__ == "__main__" :
arr = [ 3, 4, 5 ]
n = len(arr)
k = 6
print(countSubArrays(arr, n, k))
# This code is contributed by Ryuga
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the count of
// required sub-arrays
static int countSubArrays(int []arr,
int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
int bitwise_or = 0;
// Traverse sub-array [i..j]
for (int k = i; k <= j; k++)
{
bitwise_or = bitwise_or | arr[k];
}
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
public static void Main()
{
int []arr = { 3, 4, 5 };
int n = arr.Length;
int k = 6;
Console.WriteLine(countSubArrays(arr, n, k));
}
}
// This code is contributed by
// Mohit kumar
PHP
= $K)
$count += 1;
}
}
return $count;
}
// Driver code
$arr = array( 3, 4, 5 );
$n = count($arr);
$k = 6;
print(countSubArrays($arr, $n, $k));
// This code is contributed by mits
?>
Javascript
C++
// C++ implementation of the approach
#include
using namespace std;
#define N 100002
int tree[4 * N];
// Function to build the segment tree
void build(int* arr, int node, int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function to return the bitwise OR of segment [L..R]
int query(int node, int start, int end, int l, int r)
{
if (start > end || start > r || end < l) {
return 0;
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to return the count of required sub-arrays
int countSubArrays(int arr[], int n, int K)
{
// Build segment tree
build(arr, 1, 0, n - 1);
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// Query segment tree for bitwise OR
// of sub-array [i..j]
int bitwise_or = query(1, 0, n - 1, i, j);
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
int main()
{
int arr[] = { 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 6;
cout << countSubArrays(arr, n, k);
return 0;
}
Java
// Java implementation of the approach
public class Main
{
static int N = 100002;
static int tree[] = new int[4 * N];
// Function to build the segment tree
static void build(int arr[], int node,
int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function to return the bitwise OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to return the count of required sub-arrays
static int countSubArrays(int arr[], int n, int K)
{
// Build segment tree
build(arr, 1, 0, n - 1);
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
// Query segment tree for bitwise OR
// of sub-array [i..j]
int bitwise_or = query(1, 0, n - 1, i, j);
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 3, 4, 5 };
int n = arr.length;
int k = 6;
System.out.print(countSubArrays(arr, n, k));
}
}
// This code is contributed by divyesh072019
Python3
# Python implementation of the approach
N = 100002
tree = [0]*(4 * N)
# Function to build the segment tree
def build(arr, node, start, end):
if start == end:
tree[node] = arr[start]
return
mid = (start + end) >> 1
build(arr, 2 * node, start, mid)
build(arr, 2 * node + 1, mid + 1, end)
tree[node] = tree[2 * node] | tree[2 * node + 1]
# Function to return the bitwise OR of segment[L..R]
def query(node, start, end, l, r):
if start > end or start > r or end < l:
return 0
if start >= l and end <= r:
return tree[node]
mid = (start + end) >> 1
q1 = query(2 * node, start, mid, l, r)
q2 = query(2 * node + 1, mid + 1, end, l, r)
return q1 or q2
# Function to return the count of required sub-arrays
def countSubArrays(arr, n, K):
# Build segment tree
build(arr, 1, 0, n - 1)
count = 0
for i in range(n):
for j in range(n):
# Query segment tree for bitwise OR
# of sub-array[i..j]
bitwise_or = query(1, 0, n - 1, i, j)
if bitwise_or >= K:
count += 1
return count
# Driver code
arr = [3, 4, 5]
n = len(arr)
k = 6
print(countSubArrays(arr, n, k))
# This code is contributed by ankush_953
C#
// C# implementation of the approach
using System;
class GFG {
static int N = 100002;
static int[] tree = new int[4 * N];
// Function to build the segment tree
static void build(int[] arr, int node,
int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function to return the bitwise OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to return the count of required sub-arrays
static int countSubArrays(int[] arr, int n, int K)
{
// Build segment tree
build(arr, 1, 0, n - 1);
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
// Query segment tree for bitwise OR
// of sub-array [i..j]
int bitwise_or = query(1, 0, n - 1, i, j);
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
static void Main() {
int[] arr = { 3, 4, 5 };
int n = arr.Length;
int k = 6;
Console.WriteLine(countSubArrays(arr, n, k));
}
}
// This code is contributd by divyeshrabadiya07.
C++
// C++ program to implement the above approach
#include
#define N 100002
using namespace std;
int tree[4 * N];
// Function which builds the segment tree
void build(int* arr, int node, int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function that returns bitwise OR of segment [L..R]
int query(int node, int start, int end, int l, int r)
{
if (start > end || start > r || end < l) {
return 0;
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to count requisite number of subarrays
int countSubArrays(const int* arr, int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++) {
// Check for subarrays starting with index i
int low = i, high = n - 1, index = INT_MAX;
while (low <= high) {
int mid = (low + high) >> 1;
// If OR of subarray [i..mid] >= K,
// then all subsequent subarrays will have OR >= K
// therefore reduce high to mid - 1
// to find the minimal length subarray
// [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K) {
index = min(index, mid);
high = mid - 1;
}
else {
low = mid + 1;
}
}
// Increase count with number of subarrays
// having OR >= K and starting with index i
if (index != INT_MAX) {
count += n - index;
}
}
return count;
}
// Driver code
int main()
{
int arr[] = { 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
// Build segment tree.
build(arr, 1, 0, n - 1);
int k = 6;
cout << countSubArrays(arr, n, k);
return 0;
}
Java
// Java implementation of the above approach
class GFG
{
static int N = 100002;
static int tree[] = new int[4 * N];
// Function which builds the segment tree
static void build(int[] arr, int node,
int start, int end)
{
if (start == end)
{
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function that returns bitwise
// OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to count requisite number of subarrays
static int countSubArrays(int[] arr,
int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++)
{
// Check for subarrays starting with index i
int low = i, high = n - 1, index = Integer.MAX_VALUE;
while (low <= high)
{
int mid = (low + high) >> 1;
// If OR of subarray [i..mid] >= K,
// then all subsequent subarrays will
// have OR >= K therefore reduce
// high to mid - 1 to find the
// minimal length subarray
// [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K)
{
index = Math.min(index, mid);
high = mid - 1;
}
else
{
low = mid + 1;
}
}
// Increase count with number of subarrays
// having OR >= K and starting with index i
if (index != Integer.MAX_VALUE)
{
count += n - index;
}
}
return count;
}
// Driver code
public static void main(String[] args)
{
int arr[] = {3, 4, 5};
int n = arr.length;
// Build segment tree.
build(arr, 1, 0, n - 1);
int k = 6;
System.out.println(countSubArrays(arr, n, k));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program to implement the above approach
N = 100002
tree = [0 for i in range(4 * N)];
# Function which builds the segment tree
def build(arr, node, start, end):
if (start == end):
tree[node] = arr[start];
return;
mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
# Function that returns bitwise OR of segment [L..R]
def query(node, start, end, l, r):
if (start > end or start > r or end < l):
return 0;
if (start >= l and end <= r):
return tree[node];
mid = (start + end) >> 1;
q1 = query(2 * node, start, mid, l, r);
q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
# Function to count requisite number of subarrays
def countSubArrays(arr, n, K):
count = 0;
for i in range(n):
# Check for subarrays starting with index i
low = i
high = n - 1
index = 1000000000
while (low <= high):
mid = (low + high) >> 1;
# If OR of subarray [i..mid] >= K,
# then all subsequent subarrays will have OR >= K
# therefore reduce high to mid - 1
# to find the minimal length subarray
# [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K):
index = min(index, mid);
high = mid - 1;
else :
low = mid + 1;
# Increase count with number of subarrays
# having OR >= K and starting with index i
if (index != 1000000000):
count += n - index;
return count;
# Driver code
if __name__=='__main__':
arr = [ 3, 4, 5 ]
n = len(arr)
# Build segment tree.
build(arr, 1, 0, n - 1);
k = 6;
print(countSubArrays(arr, n, k))
# This code is contributed by rutvik_56.
C#
// C# implementation of the above approach
using System;
class GFG
{
static int N = 100002;
static int []tree = new int[4 * N];
// Function which builds the segment tree
static void build(int[] arr, int node,
int start, int end)
{
if (start == end)
{
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function that returns bitwise
// OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to count requisite number of subarrays
static int countSubArrays(int[] arr,
int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++)
{
// Check for subarrays starting with index i
int low = i, high = n - 1, index = int.MaxValue;
while (low <= high)
{
int mid = (low + high) >> 1;
// If OR of subarray [i..mid] >= K,
// then all subsequent subarrays will
// have OR >= K therefore reduce
// high to mid - 1 to find the
// minimal length subarray
// [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K)
{
index = Math.Min(index, mid);
high = mid - 1;
}
else
{
low = mid + 1;
}
}
// Increase count with number of subarrays
// having OR >= K and starting with index i
if (index != int.MaxValue)
{
count += n - index;
}
}
return count;
}
// Driver code
public static void Main(String[] args)
{
int []arr = {3, 4, 5};
int n = arr.Length;
// Build segment tree.
build(arr, 1, 0, n - 1);
int k = 6;
Console.WriteLine(countSubArrays(arr, n, k));
}
}
// This code is contributed by PrinciRaj1992
2
上述解决方案的时间复杂度为O(n 3 )。
一个有效的解决方案使用段树在O(log n)时间内计算子数组的按位或。因此,现在我们直接查询段树,而不是遍历子数组。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define N 100002
int tree[4 * N];
// Function to build the segment tree
void build(int* arr, int node, int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function to return the bitwise OR of segment [L..R]
int query(int node, int start, int end, int l, int r)
{
if (start > end || start > r || end < l) {
return 0;
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to return the count of required sub-arrays
int countSubArrays(int arr[], int n, int K)
{
// Build segment tree
build(arr, 1, 0, n - 1);
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// Query segment tree for bitwise OR
// of sub-array [i..j]
int bitwise_or = query(1, 0, n - 1, i, j);
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
int main()
{
int arr[] = { 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
int k = 6;
cout << countSubArrays(arr, n, k);
return 0;
}
Java
// Java implementation of the approach
public class Main
{
static int N = 100002;
static int tree[] = new int[4 * N];
// Function to build the segment tree
static void build(int arr[], int node,
int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function to return the bitwise OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to return the count of required sub-arrays
static int countSubArrays(int arr[], int n, int K)
{
// Build segment tree
build(arr, 1, 0, n - 1);
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
// Query segment tree for bitwise OR
// of sub-array [i..j]
int bitwise_or = query(1, 0, n - 1, i, j);
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 3, 4, 5 };
int n = arr.length;
int k = 6;
System.out.print(countSubArrays(arr, n, k));
}
}
// This code is contributed by divyesh072019
Python3
# Python implementation of the approach
N = 100002
tree = [0]*(4 * N)
# Function to build the segment tree
def build(arr, node, start, end):
if start == end:
tree[node] = arr[start]
return
mid = (start + end) >> 1
build(arr, 2 * node, start, mid)
build(arr, 2 * node + 1, mid + 1, end)
tree[node] = tree[2 * node] | tree[2 * node + 1]
# Function to return the bitwise OR of segment[L..R]
def query(node, start, end, l, r):
if start > end or start > r or end < l:
return 0
if start >= l and end <= r:
return tree[node]
mid = (start + end) >> 1
q1 = query(2 * node, start, mid, l, r)
q2 = query(2 * node + 1, mid + 1, end, l, r)
return q1 or q2
# Function to return the count of required sub-arrays
def countSubArrays(arr, n, K):
# Build segment tree
build(arr, 1, 0, n - 1)
count = 0
for i in range(n):
for j in range(n):
# Query segment tree for bitwise OR
# of sub-array[i..j]
bitwise_or = query(1, 0, n - 1, i, j)
if bitwise_or >= K:
count += 1
return count
# Driver code
arr = [3, 4, 5]
n = len(arr)
k = 6
print(countSubArrays(arr, n, k))
# This code is contributed by ankush_953
C#
// C# implementation of the approach
using System;
class GFG {
static int N = 100002;
static int[] tree = new int[4 * N];
// Function to build the segment tree
static void build(int[] arr, int node,
int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function to return the bitwise OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to return the count of required sub-arrays
static int countSubArrays(int[] arr, int n, int K)
{
// Build segment tree
build(arr, 1, 0, n - 1);
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
// Query segment tree for bitwise OR
// of sub-array [i..j]
int bitwise_or = query(1, 0, n - 1, i, j);
if (bitwise_or >= K)
count++;
}
}
return count;
}
// Driver code
static void Main() {
int[] arr = { 3, 4, 5 };
int n = arr.Length;
int k = 6;
Console.WriteLine(countSubArrays(arr, n, k));
}
}
// This code is contributd by divyeshrabadiya07.
2
上述解决方案的时间复杂度为O(n 2 log n)。
另一种有效的解决方案是使用二进制搜索。按位或运算是一个永远不会随着输入数量而减少的函数。例如:
OR(a, b) ≤ OR(a, b, c)
OR(a1, a2, a3, …) ≤ OR(a1, a2, a3, …, b)
通过此属性, OR(a i ,…,a j )<= OR(a i ,…,a j ,a j + 1 ) 。因此,如果OR(a i ,…,a j )大于K,则OR(a i ,…,a j , j + 1 )也将大于K。因此,一旦找到子数组[i。 .j]的OR大于K,我们不需要检查子数组[i..j + 1],[i..j + 2],..等等,因为它们的OR也将大于K.我们可以将剩余子数组的数量添加到当前总和中。使用二进制搜索找到从特定起点开始的第一个子数组,该数组的OR大于K。
下面是上述想法的实现:
C++
// C++ program to implement the above approach
#include
#define N 100002
using namespace std;
int tree[4 * N];
// Function which builds the segment tree
void build(int* arr, int node, int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function that returns bitwise OR of segment [L..R]
int query(int node, int start, int end, int l, int r)
{
if (start > end || start > r || end < l) {
return 0;
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to count requisite number of subarrays
int countSubArrays(const int* arr, int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++) {
// Check for subarrays starting with index i
int low = i, high = n - 1, index = INT_MAX;
while (low <= high) {
int mid = (low + high) >> 1;
// If OR of subarray [i..mid] >= K,
// then all subsequent subarrays will have OR >= K
// therefore reduce high to mid - 1
// to find the minimal length subarray
// [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K) {
index = min(index, mid);
high = mid - 1;
}
else {
low = mid + 1;
}
}
// Increase count with number of subarrays
// having OR >= K and starting with index i
if (index != INT_MAX) {
count += n - index;
}
}
return count;
}
// Driver code
int main()
{
int arr[] = { 3, 4, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
// Build segment tree.
build(arr, 1, 0, n - 1);
int k = 6;
cout << countSubArrays(arr, n, k);
return 0;
}
Java
// Java implementation of the above approach
class GFG
{
static int N = 100002;
static int tree[] = new int[4 * N];
// Function which builds the segment tree
static void build(int[] arr, int node,
int start, int end)
{
if (start == end)
{
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function that returns bitwise
// OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to count requisite number of subarrays
static int countSubArrays(int[] arr,
int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++)
{
// Check for subarrays starting with index i
int low = i, high = n - 1, index = Integer.MAX_VALUE;
while (low <= high)
{
int mid = (low + high) >> 1;
// If OR of subarray [i..mid] >= K,
// then all subsequent subarrays will
// have OR >= K therefore reduce
// high to mid - 1 to find the
// minimal length subarray
// [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K)
{
index = Math.min(index, mid);
high = mid - 1;
}
else
{
low = mid + 1;
}
}
// Increase count with number of subarrays
// having OR >= K and starting with index i
if (index != Integer.MAX_VALUE)
{
count += n - index;
}
}
return count;
}
// Driver code
public static void main(String[] args)
{
int arr[] = {3, 4, 5};
int n = arr.length;
// Build segment tree.
build(arr, 1, 0, n - 1);
int k = 6;
System.out.println(countSubArrays(arr, n, k));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program to implement the above approach
N = 100002
tree = [0 for i in range(4 * N)];
# Function which builds the segment tree
def build(arr, node, start, end):
if (start == end):
tree[node] = arr[start];
return;
mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
# Function that returns bitwise OR of segment [L..R]
def query(node, start, end, l, r):
if (start > end or start > r or end < l):
return 0;
if (start >= l and end <= r):
return tree[node];
mid = (start + end) >> 1;
q1 = query(2 * node, start, mid, l, r);
q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
# Function to count requisite number of subarrays
def countSubArrays(arr, n, K):
count = 0;
for i in range(n):
# Check for subarrays starting with index i
low = i
high = n - 1
index = 1000000000
while (low <= high):
mid = (low + high) >> 1;
# If OR of subarray [i..mid] >= K,
# then all subsequent subarrays will have OR >= K
# therefore reduce high to mid - 1
# to find the minimal length subarray
# [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K):
index = min(index, mid);
high = mid - 1;
else :
low = mid + 1;
# Increase count with number of subarrays
# having OR >= K and starting with index i
if (index != 1000000000):
count += n - index;
return count;
# Driver code
if __name__=='__main__':
arr = [ 3, 4, 5 ]
n = len(arr)
# Build segment tree.
build(arr, 1, 0, n - 1);
k = 6;
print(countSubArrays(arr, n, k))
# This code is contributed by rutvik_56.
C#
// C# implementation of the above approach
using System;
class GFG
{
static int N = 100002;
static int []tree = new int[4 * N];
// Function which builds the segment tree
static void build(int[] arr, int node,
int start, int end)
{
if (start == end)
{
tree[node] = arr[start];
return;
}
int mid = (start + end) >> 1;
build(arr, 2 * node, start, mid);
build(arr, 2 * node + 1, mid + 1, end);
tree[node] = tree[2 * node] | tree[2 * node + 1];
}
// Function that returns bitwise
// OR of segment [L..R]
static int query(int node, int start,
int end, int l, int r)
{
if (start > end || start > r || end < l)
{
return 0;
}
if (start >= l && end <= r)
{
return tree[node];
}
int mid = (start + end) >> 1;
int q1 = query(2 * node, start, mid, l, r);
int q2 = query(2 * node + 1, mid + 1, end, l, r);
return q1 | q2;
}
// Function to count requisite number of subarrays
static int countSubArrays(int[] arr,
int n, int K)
{
int count = 0;
for (int i = 0; i < n; i++)
{
// Check for subarrays starting with index i
int low = i, high = n - 1, index = int.MaxValue;
while (low <= high)
{
int mid = (low + high) >> 1;
// If OR of subarray [i..mid] >= K,
// then all subsequent subarrays will
// have OR >= K therefore reduce
// high to mid - 1 to find the
// minimal length subarray
// [i..mid] having OR >= K
if (query(1, 0, n - 1, i, mid) >= K)
{
index = Math.Min(index, mid);
high = mid - 1;
}
else
{
low = mid + 1;
}
}
// Increase count with number of subarrays
// having OR >= K and starting with index i
if (index != int.MaxValue)
{
count += n - index;
}
}
return count;
}
// Driver code
public static void Main(String[] args)
{
int []arr = {3, 4, 5};
int n = arr.Length;
// Build segment tree.
build(arr, 1, 0, n - 1);
int k = 6;
Console.WriteLine(countSubArrays(arr, n, k));
}
}
// This code is contributed by PrinciRaj1992
2
上述解决方案的时间复杂度为O(n log 2 n) 。