Queries to count integers in a range [L, R] such that their digit sum is prime and divisible by K

Given Q queries and an integer K where each query consists of a range [L, R] and the task is to find the count of integers in the given range whose digit sum is prime and divisible by K.

Example:

Input: Q = { {1, 11},
      {5, 15},
      {2, 24} } 
K = 2
Output: 
2
1
3
Explanation:
Query 1: 2 and 11 are the only 
numbers in the given range whose 
digit sum is prime and divisible by K.
Query 2: 11 is the only number.
Query 3: 2, 11 and 20.

Input: Q = { {2, 17},
             {3, 24} }
K = 3
Output:
2
3

Approach:



  • First pre-compute all the primes till the maximum possible value of R among all the given ranges say maxVal using Sieve of Eratosthenes.
  • Then mark all the integers from 1 to maxVal which are divisible by K and are prime.
  • Take the prefix sum of the marked array.
  • Answer the given queries by prefix[right] – prefix[left – 1].

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
const int maxSize = 1e5 + 1;
bool isPrime[maxSize];
int prefix[maxSize];
  
// Function to return the
// digit sum of num
int digitSum(int num)
{
    int s = 0;
    while (num != 0) {
        s = s + num % 10;
        num = num / 10;
    }
    return s;
}
  
// Sieve Function to generate
// all primes opto maxSize
void sieveOfEratosthenes()
{
    for (int i = 2; i < maxSize; i++) {
        isPrime[i] = true;
    }
  
    for (int i = 2; i * i <= maxSize; i++) {
        if (isPrime[i]) {
            for (int j = i * i; j < maxSize; j += i) {
                isPrime[j] = false;
            }
        }
    }
}
  
// Pre-Computation till maxSize
// and for a given K
void precompute(int k)
{
    sieveOfEratosthenes();
    for (int i = 1; i < maxSize; i++) {
        // Getting Digit Sum
        int sum = digitSum(i);
        // Check if the digit sum
        // is prime and divisible by k
        if (isPrime[sum] == true && sum % k == 0) {
            prefix[i]++;
        }
    }
  
    // Taking Prefix Sum
    for (int i = 1; i < maxSize; i++) {
        prefix[i] = prefix[i] + prefix[i - 1];
    }
}
  
// Function to perform the queries
void performQueries(int k, int q,
                    vector<vector<int> >& query)
{
    // Precompute the results
    precompute(k);
  
    vector<int> ans;
    for (int i = 0; i < q; i++) {
        int l = query[i][0], r = query[i][1];
  
        // Getting count of range in range [L, R]
        int cnt = prefix[r] - prefix[l - 1];
        cout << cnt << endl;
    }
}
  
// Driver code
int main()
{
    vector<vector<int> > query = { { 1, 11 },
                                   { 5, 15 },
                                   { 2, 24 } };
    int k = 2, q = query.size();
    performQueries(k, q, query);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GFG 
{
    static final int maxSize = (int)1e5 + 1
    static boolean isPrime[] = new boolean[maxSize]; 
    static int prefix[] = new int[maxSize]; 
      
    // Function to return the 
    // digit sum of num 
    static int digitSum(int num) 
    
        int s = 0
        while (num != 0)
        
            s = s + num % 10
            num = num / 10
        
        return s; 
    
      
    // Sieve Function to generate 
    // all primes opto maxSize 
    static void sieveOfEratosthenes() 
    
        for (int i = 2; i < maxSize; i++) 
        
            isPrime[i] = true
        
      
        for (int i = 2; i * i <= maxSize; i++)
        
            if (isPrime[i]) 
            
                for (int j = i * i; 
                         j < maxSize; j += i) 
                
                    isPrime[j] = false
                
            
        
    
      
    // Pre-Computation till maxSize 
    // and for a given K 
    static void precompute(int k) 
    
        sieveOfEratosthenes(); 
          
        for (int i = 1; i < maxSize; i++) 
        
              
            // Getting Digit Sum 
            int sum = digitSum(i); 
              
            // Check if the digit sum 
            // is prime and divisible by k 
            if (isPrime[sum] == true && 
                        sum % k == 0)
            
                prefix[i]++; 
            
        
      
        // Taking Prefix Sum 
        for (int i = 1; i < maxSize; i++) 
        
            prefix[i] = prefix[i] + 
                        prefix[i - 1]; 
        
    
      
    // Function to perform the queries 
    static void performQueries(int k, int q,
                               int query[][]) 
    
        // Precompute the results 
        precompute(k); 
          
        for (int i = 0; i < q; i++) 
        
            int l = query[i][0], r = query[i][1]; 
      
            // Getting count of range in range [L, R] 
            int cnt = prefix[r] - prefix[l - 1]; 
              
            System.out.println(cnt); 
        
    
      
    // Driver code 
    public static void main (String[] args)
    
        int query[][] = { { 1, 11 }, 
                          { 5, 15 }, 
                          { 2, 24 } }; 
        int k = 2, q = query.length; 
        performQueries(k, q, query); 
    
}
  
// This Code is contributed by AnkitRai01

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
from math import sqrt
  
maxSize = 10 ** 5 + 1
isPrime = [0] * maxSize; 
prefix = [0] * maxSize; 
  
# Function to return the 
# digit sum of num 
def digitSum(num) :
      
    s = 0
    while (num != 0) :
        s = s + num % 10
        num = num // 10
  
    return s; 
  
# Sieve Function to generate 
# all primes opto maxSize 
def sieveOfEratosthenes() :
  
    for i in range(2, maxSize) :
        isPrime[i] = True
  
    for i in range(2, int(sqrt(maxSize)) + 1) :
        if (isPrime[i]) :
            for j in range(i * i, maxSize, i) : 
                isPrime[j] = False
          
# Pre-Computation till maxSize 
# and for a given K 
def precompute(k) : 
  
    sieveOfEratosthenes(); 
      
    for i in range(1, maxSize) : 
          
        # Getting Digit Sum 
        sum = digitSum(i); 
          
        # Check if the digit sum 
        # is prime and divisible by k 
        if (isPrime[sum] == True and 
                    sum % k == 0) :
            prefix[i] += 1;
  
    # Taking Prefix Sum 
    for i in range(1, maxSize) :
        prefix[i] = prefix[i] + prefix[i - 1]; 
  
# Function to perform the queries 
def performQueries(k, q, query) : 
  
    # Precompute the results 
    precompute(k); 
  
    for i in range(q) :
        l = query[i][0]; r = query[i][1]; 
  
        # Getting count of range in range [L, R] 
        cnt = prefix[r] - prefix[l - 1]; 
        print(cnt); 
          
# Driver code 
if __name__ == "__main__" :
  
    query = [ [ 1, 11 ], 
              [ 5, 15 ], 
              [ 2, 24 ] ]; 
              
    k = 2; q = len(query); 
    performQueries(k, q, query); 
      
# This code is contributed by kanugargng

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the above approach 
using System;
      
class GFG 
{
    static readonly int maxSize = (int)1e5 + 1; 
    static Boolean []isPrime = new Boolean[maxSize]; 
    static int []prefix = new int[maxSize]; 
      
    // Function to return the 
    // digit sum of num 
    static int digitSum(int num) 
    
        int s = 0; 
        while (num != 0)
        
            s = s + num % 10; 
            num = num / 10; 
        
        return s; 
    
      
    // Sieve Function to generate 
    // all primes opto maxSize 
    static void sieveOfEratosthenes() 
    
        for (int i = 2; i < maxSize; i++) 
        
            isPrime[i] = true
        
      
        for (int i = 2; i * i <= maxSize; i++)
        
            if (isPrime[i]) 
            
                for (int j = i * i; 
                         j < maxSize; j += i) 
                
                    isPrime[j] = false
                
            
        
    
      
    // Pre-Computation till maxSize 
    // and for a given K 
    static void precompute(int k) 
    
        sieveOfEratosthenes(); 
          
        for (int i = 1; i < maxSize; i++) 
        
              
            // Getting Digit Sum 
            int sum = digitSum(i); 
              
            // Check if the digit sum 
            // is prime and divisible by k 
            if (isPrime[sum] == true && 
                        sum % k == 0)
            
                prefix[i]++; 
            
        
      
        // Taking Prefix Sum 
        for (int i = 1; i < maxSize; i++) 
        
            prefix[i] = prefix[i] + 
                        prefix[i - 1]; 
        
    
      
    // Function to perform the queries 
    static void performQueries(int k, int q,
                               int [,]query) 
    
        // Precompute the results 
        precompute(k); 
          
        for (int i = 0; i < q; i++) 
        
            int l = query[i, 0], r = query[i, 1]; 
      
            // Getting count of range in range [L, R] 
            int cnt = prefix[r] - prefix[l - 1]; 
              
            Console.WriteLine(cnt); 
        
    
      
    // Driver code 
    public static void Main (String[] args)
    
        int [,]query = {{ 1, 11 }, 
                        { 5, 15 }, 
                        { 2, 24 }}; 
        int k = 2, q = query.GetLength(0); 
        performQueries(k, q, query); 
    
}
  
// This code is contributed by PrinciRaj1992

chevron_right


Output:

2
1
3


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.