I am trying to solve the following exercise:
There is an array of positive integers with size N given 1 <= N <= 2*105. Each element of the array is at most 105 at all times.
After reading in these N integers, you need to support Q queries (1 <= Q <= 105).Each query asks one of the below:
Count divisibility (represented by letter Q in input):
Find the number of elements in a subarray that are divisible by a given input value. For this query, you are given 3 integers: the left end of the subarray, the right end of the subarray, and the integer to count divisibility for.Update (represented by letter U in input):
Change the element at some index to a new value. For this query, you are given 2 integers: the index to change and the new value.
I have a O(NQ) brute force solution but it times out. Any ideas how to solve this in better time complexity?
The input is N and Q on the first line. The next line has all the starting elements of the array separated by spaces.
The next Q lines each contain one query. The parts of the query are separated by spaces and the indexes are 0 based.
Example input:
6 4
6 5 4 3 2 1
Q 0 3 1
Q 1 4 2
U 3 8
Q 1 5 2
The ideal output is (each query for the count of divisible elements should be answered on a new line)
4
2
3
My brute force code is this (too slow however):
#include <iostream>
#include <vector>
int main() {
using std::cin, std::cout;
int N, Q;
cin >> N >> Q;
std::vector<int> array(N);
for (int &i : array) cin >> i; // read starting array elements
for (int q = 0; q < Q; q++) {
char t;
cin >> t;
if (t == 'Q') {
// query how many numbers in array between index left and right are divisible by num
int left, right, num;
cin >> left >> right >> num;
int cnt = 0;
for (int i = left; i <= right; i++) {
if (array[i] % num == 0) {
cnt++;
}
}
cout << cnt << '\n'; // don't use endl when there's a lot of output
} else {
// simple update on one element in array
int index, newNum;
cin >> index >> newNum;
array[index] = newNum;
}
}
return 0;
}
std::setmight allow to have logarithmic search by query instead of linear in your brute force solution.std::cin.tie(nullptr);, for example, is premature optimization. In general, just callingstd::ios_base::sync_with_stdio(false); std::cin.tie(nullptr);will make I/O fast enough for any problem. "A simple total iteration seems to be the only option" - This is not even close to true.O(NQ)has already been said to be too slow. Look at the answers below for more efficient solutions. If you can't think of anything, consider order statistic trees, square root decomposition, etc.