Find the Number of subarrays having sum of the form k^m, m >= 0 using C++

C++Server Side ProgrammingProgramming

<p>In this article, we will explain everything about solving the number of subarrays having the sum of the form k^m, m &gt;= 0 in C++. Given an array arr[] and an integer K, we need to find the number of subarrays having sum in the form of K^m where m is greater than equal to zero, or we can say we need to find the number of subarrays having sum equal to some non-negative power of K.</p><pre class="result notranslate">Input: arr[] = { 2, 2, 2, 2 } K = 2 Output: 8 Sub-arrays with below indexes are valid: [1, 1], [2, 2], [3, 3], [4, 4], [1, 2], [2, 3], [3, 4], [1, 4] Input: arr[] = { 3, -6, -3, 12 } K = -3 Output: 3</pre><p>There are mainly two approaches that come to mind &minus;</p><h2>Brute Force</h2><p>In this approach, we will go through all the subarrays and check if they are some positive integral power of K or not; if yes, then we increment the count.</p><h2>Example</h2><pre class="demo-code notranslate language-cpp" data-lang="cpp">#include &lt;bits/stdc++.h&gt; #define MAX 1000000 using namespace std; int main(){ &nbsp; &nbsp;int arr[] = {2, 2, 2, 2}; // given array &nbsp; &nbsp;int k = 2; // given integer &nbsp; &nbsp;int n = sizeof(arr) / sizeof(arr[0]); // the size of our array &nbsp; &nbsp;int answer = 0; // counter variable &nbsp; &nbsp;for(int i = 0; i &lt; n; i++){ &nbsp; &nbsp; &nbsp; int sum = 0; &nbsp; &nbsp; &nbsp; for(int j = i; j &lt; n; j++){ // this will loop will make all the subarrays &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sum += arr[j]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int b = 1; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;while(b &lt; MAX &amp;&amp; sum &gt; b) // k^m Max should be 10^6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b *= k; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(b == sum) // if b == sum then increment count &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; answer++; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp;} &nbsp; &nbsp;cout &lt;&lt; answer &lt;&lt; &quot; &quot;; }</pre><h2>Output</h2><pre class="result notranslate">8</pre><p>However, this approach is not very good as the time complexity of this program is <strong>O(N*N*log(K)),</strong> where N is the size of our array and K is the integer given by the user.</p><p>This complexity is not good as this complexity can be used for higher constraints as it will take too much time to process if the constraints are big, so we will try another approach so that we can use the program for higher constraints.</p><h2>Efficient Approach</h2><p>In this approach, we will use a prefix sum and map to reduce our processing that will drastically decrease our time complexity.</p><h2>Example</h2><pre class="demo-code notranslate language-cpp" data-lang="cpp">#include &lt;bits/stdc++.h&gt; #define ll long long #define MAX 1000000 using namespace std; int main(){ &nbsp; &nbsp;int arr[] = {2, 2, 2, 2}; // The given array &nbsp; &nbsp;int n = sizeof(arr) / sizeof(arr[0]); // size of our array &nbsp; &nbsp;int k = 2; // given integer &nbsp; &nbsp;ll prefix_sum[MAX]; &nbsp; &nbsp;prefix_sum[0] = 0; &nbsp; &nbsp;partial_sum(arr, arr + n, prefix_sum + 1); // making prefix sum array &nbsp; &nbsp;ll sum; &nbsp; &nbsp;if (k == 1){ &nbsp; &nbsp;// we are going to check separately for 1 &nbsp; &nbsp; &nbsp; sum = 0; &nbsp; &nbsp; &nbsp; map&lt;ll, int&gt; m; &nbsp; &nbsp;for (int i = n; i &gt;= 0; i--){ &nbsp; &nbsp; &nbsp; // If m[a+b] = c, then add c to the current sum. &nbsp; &nbsp; &nbsp; if (m.find(prefix_sum[i] + 1) != m.end()) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sum += m[prefix_sum[i] + 1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Increase count of prefix sum. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m[prefix_sum[i]]++; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; cout &lt;&lt; sum &lt;&lt; &quot; &quot;; &nbsp; &nbsp;} &nbsp; &nbsp;else if (k == -1){ &nbsp; &nbsp; &nbsp; // we are going to check separately for -1 &nbsp; &nbsp; &nbsp; sum = 0; &nbsp; &nbsp; &nbsp; map&lt;ll, int&gt; m; &nbsp; &nbsp; &nbsp; for (int i = n; i &gt;= 0; i--){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// If m[a+b] = c, then add c to the current sum. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (m.find(prefix_sum[i] + 1) != m.end()) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum += m[prefix_sum[i] + 1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (m.find(prefix_sum[i] - 1) != m.end()) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sum += m[prefix_sum[i] - 1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Increase count of prefix sum. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m[prefix_sum[i]]++; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; cout &lt;&lt; sum &lt;&lt; &quot; &quot;; &nbsp; &nbsp;} &nbsp; &nbsp;else{ &nbsp; &nbsp; &nbsp; sum = 0; &nbsp; &nbsp; &nbsp; ll b; &nbsp; &nbsp; &nbsp; map&lt;ll, int&gt; m; &nbsp; &nbsp; &nbsp; for (int i = n; i &gt;= 0; i--){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b = 1; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;while (b &lt; MAX){ // we are not going to check for more than 10^6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // If m[a+b] = c, then add c to the current sum. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (m.find(prefix_sum[i] + b) != m.end()) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sum += m[prefix_sum[i] + b]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b *= k; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m[prefix_sum[i]]++; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; cout &lt;&lt; sum &lt;&lt; &quot; &quot;; &nbsp; &nbsp;} &nbsp; &nbsp;return 0; }</pre><h2>Output</h2><pre class="result notranslate">8</pre><h2>Conclusion</h2><p>We solve a problem to find the Number of subarrays having sum in the form of k^m where m &gt;= 0 in <strong>O(nlog(k)log(n))</strong> time complexity. We also learned the C++ program for this problem and the complete approach ( Normal and efficient ) by which we solved this problem. We can write the same program in other languages such as C, java, python, and other languages. Hope you find this article helpful.</p>
raja
Updated on 25-Nov-2021 05:32:32

Advertisements