给定一个包含N个元素的数组arr []和一个Q []数组,每个查询的任务是找到最长前缀的长度,以使该前缀的所有元素都可以被K整除。
例子:
Input: arr[] = {12, 6, 15, 3, 10}, Q[] = {4, 3, 2}
Output: 1 4 2
Explanation:
- Q[0] = 4: arr[0] (= 12) is divisible by 4. arr[1] is not divisible by 4. Therefore, the length of the longest prefix divisible by 4 is 1.
- Q[1] = 3: The longest prefix which is divisible by 3 is {12, 6, 15, 3}. Therefore, print 4 as the required output.
- Q[2] = 2: The longest prefix which is divisible by 2 is {12, 6}.
Input: arr[] = {4, 3, 2, 1}, Q[] = {1, 2, 3}
Output: 4 1 0
方法:想法是观察到,如果数组的前i个元素可以被给定的整数K整除,那么它们的GCD也可以被K整除。请按照以下步骤解决问题:
- 在找到每个查询的答案之前,请预先计算另一个数组g []中数组前缀的gcd,以使g [0] = arr [0] ,而其余元素g [i] = GCD(arr [i],g [i – 1]) 。
- 然后,对于在阵列每个元素[],在阵列克[]执行二进制搜索,找到克的最后一个索引[]其是由Q [I]整除。
- 必须注意的是,该索引之前的所有元素都可以被K整除,因为直到该索引为止的所有元素的gcd都可以被K整除。
- 打印最长前缀的长度。
下面是上述方法的实现。
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find index of the last
// element which is divisible the given element
int binSearch(int* g, int st, int en, int val)
{
// Initially assume the
// index to be -1
int ind = -1;
while (st <= en) {
// Find the mid element
// of the subarray
int mid = st + (en - st) / 2;
// If the mid element is divisible by
// given element, then move to right
// of mid and update ind to mid
if (g[mid] % val == 0) {
ind = mid;
st = mid + 1;
}
// Otherwise, move to left of mid
else {
en = mid - 1;
}
}
// Return the length of prefix
return ind + 1;
}
// Function to compute and print for each query
void solveQueries(int* arr, int* queries,
int n, int q)
{
int g[n];
// Pre compute the gcd of the prefixes
// of the input array in the array g[]
for (int i = 0; i < n; i++) {
if (i == 0) {
g[i] = arr[i];
}
else {
g[i] = __gcd(g[i - 1], arr[i]);
}
}
// Perform binary search
// for each query
for (int i = 0; i < q; i++) {
cout << binSearch(g, 0, n - 1,
queries[i])
<< " ";
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 12, 6, 15, 3, 10 };
// Size of array
int n = sizeof(arr) / sizeof(arr[0]);
// Given Queries
int queries[] = { 4, 3, 2 };
// Size of queries
int q = sizeof(queries) / sizeof(queries[0]);
solveQueries(arr, queries, n, q);
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function to find index of the last
// element which is divisible the given element
static int binSearch(int[] g, int st, int en, int val)
{
// Initially assume the
// index to be -1
int ind = -1;
while (st <= en)
{
// Find the mid element
// of the subarray
int mid = st + (en - st) / 2;
// If the mid element is divisible by
// given element, then move to right
// of mid and update ind to mid
if (g[mid] % val == 0)
{
ind = mid;
st = mid + 1;
}
// Otherwise, move to left of mid
else
{
en = mid - 1;
}
}
// Return the length of prefix
return ind + 1;
}
// Function to compute and print for each query
static void solveQueries(int []arr, int []queries,
int n, int q)
{
int []g = new int[n];
// Pre compute the gcd of the prefixes
// of the input array in the array g[]
for (int i = 0; i < n; i++)
{
if (i == 0) {
g[i] = arr[i];
}
else {
g[i] = __gcd(g[i - 1], arr[i]);
}
}
// Perform binary search
// for each query
for (int i = 0; i < q; i++)
{
System.out.print(binSearch(g, 0, n - 1,
queries[i])
+ " ");
}
}
static int __gcd(int a, int b)
{
return b == 0? a:__gcd(b, a % b);
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 12, 6, 15, 3, 10 };
// Size of array
int n = arr.length;
// Given Queries
int queries[] = { 4, 3, 2 };
// Size of queries
int q = queries.length;
solveQueries(arr, queries, n, q);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach
from math import gcd as __gcd
# Function to find index of the last
# element which is divisible the
# given element
def binSearch(g, st, en, val):
# Initially assume the
# index to be -1
ind = -1
while (st <= en):
# Find the mid element
# of the subarray
mid = st + (en - st) // 2
# If the mid element is divisible by
# given element, then move to right
# of mid and update ind to mid
if (g[mid] % val == 0):
ind = mid
st = mid + 1
# Otherwise, move to left of mid
else:
en = mid - 1
# Return the length of prefix
return ind + 1
# Function to compute and prfor each query
def solveQueries(arr, queries, n, q):
g = [0 for i in range(n)]
# Pre compute the gcd of the prefixes
# of the input array in the array g[]
for i in range(n):
if (i == 0):
g[i] = arr[i]
else:
g[i] = __gcd(g[i - 1], arr[i])
# Perform binary search
# for each query
for i in range(q):
print(binSearch(g, 0, n - 1,
queries[i]), end = " ")
# Driver Code
if __name__ == '__main__':
# Given array
arr = [ 12, 6, 15, 3, 10 ]
# Size of array
n = len(arr)
# Given Queries
queries = [ 4, 3, 2 ]
# Size of queries
q = len(queries)
solveQueries(arr, queries, n, q)
# This code is contributed by mohit kumar 29
C#
// C# program to implement
// the above approach
using System;
class GFG
{
// Function to find index of the last
// element which is divisible the given element
static int binSearch(int[] g, int st, int en, int val)
{
// Initially assume the
// index to be -1
int ind = -1;
while (st <= en)
{
// Find the mid element
// of the subarray
int mid = st + (en - st) / 2;
// If the mid element is divisible by
// given element, then move to right
// of mid and update ind to mid
if (g[mid] % val == 0)
{
ind = mid;
st = mid + 1;
}
// Otherwise, move to left of mid
else
{
en = mid - 1;
}
}
// Return the length of prefix
return ind + 1;
}
// Recursive function to return
// gcd of a and b
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0)
return b;
if (b == 0)
return a;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
// Function to compute and print for each query
static void solveQueries(int[] arr, int[] queries,
int n, int q)
{
int[] g = new int[n];
// Pre compute the gcd of the prefixes
// of the input array in the array g[]
for (int i = 0; i < n; i++)
{
if (i == 0)
{
g[i] = arr[i];
}
else
{
g[i] = gcd(g[i - 1], arr[i]);
}
}
// Perform binary search
// for each query
for (int i = 0; i < q; i++)
{
Console.Write(binSearch(g, 0, n - 1,
queries[i]) + " ");
}
}
// Driver code
public static void Main()
{
// Given array
int[] arr = { 12, 6, 15, 3, 10 };
// Size of array
int n = arr.Length;
// Given Queries
int[] queries = { 4, 3, 2 };
// Size of queries
int q = queries.Length;
solveQueries(arr, queries, n, q);
}
}
// This code is contributed by susmitakundugoaldanga
输出:
1 4 2
时间复杂度: O(NlogN + QlogN)
辅助空间: O(N)