Faster way to compute the Sum of this function below? - c++

I have this problem I'm curious about where I have an Array and I need to compute the Sum of this function:
Arr[L] + (Arr[L] ^ Arr[L+1]) + ... + (Arr[L] ^ Arr[L+1] ^ ... ^ Arr[R])
Example:
If the Array given was: [1, 2, 3, 5] and I asked what's the sum on the range [L = 1, R = 3] (assuming 1-based Index), then it'd be:
Sum = 1 + (1 ^ 2) + (1 ^ 2 ^ 3) = 4
In this problem, the Array, the size of the Array, and the Ranges are given. My approach for this is too slow.
There's also a variable called Q which indicates the number of Queries that would process each [L, R].
What I have:
I XOR'ed each element and then summed it to a variable within the range of [L, R]. Is there any faster way to compute this if the elements in the Array are suppose... 1e18 or 1e26 larger?
#include <iostream>
#include <array>
int main (int argc, const char** argv)
{
long long int N, L, R;
std::cin >> N;
long long int Arr[N];
for (long long int i = 0; i < N; i++)
{
std::cin >> Arr[i];
}
std::cin >> L >> R;
long long int Summation = 0, Answer = 0;
for (long long int i = L; i <= R; i++)
{
Answer = Answer ^ Arr[i - 1];
Summation += Answer;
}
std::cout << Summation << '\n';
return 0;
}

There are two loops in your code:
for (long long int i = 0; i < N; i++)
{
std::cin >> Arr[i];
}
long long int Summation = 0, Answer = 0;
for (long long int i = L; i <= R; i++)
{
Answer = Answer ^ Arr[i - 1];
Summation += Answer;
}
The second loop is smaller, and only does two operations (^= and +). These are native CPU instructions; this will be memory bound on the sequential access of Arr[]. You can't speed this up. You need all elements, and it doesn't get faster than a single sequential scan. The CPU prefetcher will hit maximum memory bandwidth.
However, the killer is the first loop. Parsing digits takes many, many more operations, and the range is even larger.

Disclaimer : NOT A FASTER SOLUTION !
Changing a bit the subject by making L and R valid indices of an integer matrix ( range [0, size) ), the following function is working for me:
size_t xor_rec(size_t* array, size_t size, size_t l, size_t r) {
if (l < 0 || r >= size || l > r) {
return 0; // error control
}
if (r > l + 1) {
size_t prev_to_prev_sum = xor_rec(array, size, l, r - 2);
size_t prev_sum = xor_rec(array, size, l, r - 1);
return prev_sum + ((prev_sum - prev_to_prev_sum) ^ array[r]);
}
if (r == l + 1) {
return array[r - 1] + (array[r - 1] ^ array[r]);
}
if (r == l) {
return array[r];
}
return 0;
}
Edit: changed int for size_t.

If indices are 0 based. That is L=0 implies the first element: Arr[0] is the first element in the array, then it's simply this:
int sum = 0;
int prev = 0;
for (int i = L; i <= R; i++)
{
int current = (prev ^ Arr[i]);
sum += current;
prev = current;
}
If it's 1 based, where L=1 is really Arr[0], then it's a quick adjustment:
int sum = 0;
int prev = 0;
for (int i = L; i <= R; i++)
{
int current = (prev ^ Arr[i-1]);
sum += current;
prev = current;
}

Related

Kth smallest element- can't create array more than the size of k

I have implemented an algorithm that solves the problem of finding the kth smallest element in an unsorted array. I have used the heap structure, and optimized the code by relying on this formula,
k1 = n - k + 1
k1 being the k1th largest element, so I go for the smaller of k and k1.
Still, I couldn't pass the time limit error on an online judge. I don't know if there will be any further more better complexity having in mind that I have to create an array no more than the size of k; maybe less than k possible? Or there is another way to solve this problem other than using the heap structure.
1 <= k <= n <= 105
The code:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
void minHeapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
if (l < n && arr[l] < arr[largest])
largest = l;
if (r < n && arr[r] < arr[largest])
largest = r;
if (largest != i) {
swap(arr[i], arr[largest]);
minHeapify(arr, n, largest);
}
}
void maxHeapify(int arr[], int n, int i)
{
int smallest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
if (l < n && arr[l] > arr[smallest])
smallest = l;
if (r < n && arr[r] > arr[smallest])
smallest = r;
if (smallest != i) {
swap(arr[i], arr[smallest]);
maxHeapify(arr, n, smallest);
}
}
void buildMinHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
minHeapify(a, n, i);
}
void buildMaxHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
maxHeapify(a, n, i);
}
int kthsmallest(int minHeap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> minHeap[i];
buildMaxHeap(minHeap, k);
for (i = k; i < n; i++)
{
cin >> temp;
if (temp < minHeap[0])
{
minHeap[0] = temp;
maxHeapify(minHeap, k, 0);
}
}
return minHeap[0];
}
int kthlargest(int minHeap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> minHeap[i];
buildMinHeap(minHeap, k);
for (i = k; i < n; i++)
{
cin >> temp;
if (temp > minHeap[0])
{
minHeap[0] = temp;
minHeapify(minHeap, k, 0);
}
}
return minHeap[0];
}
int main() {//kth smallest element
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, k1;
cin >> n >> k;
k1 = n - k + 1;//kth smallest element is the same as k1th largest element
if (k < k1) {
int *minHeap = new int[k];
cout << kthsmallest(minHeap, k, n);
}
else {
int *minHeap = new int[k1];
cout << kthlargest(minHeap, k1, n);
}
return 0;
}
Please if you could help finding a better time complexity?
Problem:
Find the kth largest element of an array
Memory limit: 256 MBs
Time limit: 1 s
Input: input.txt
Output: output.txt
Task:
You are given an array of n integers and a natural k.
You have to find the kth largest element of the array.
You can't create array consisting of more than k elements.
Input:
The first line contains a natural n (1 ≤ n≤105) – the
quantity of elements of the array, and the natural k.
The second line contains n numbers – the elements of the array.
Output:
The kth largest element of the array.
Example:
Input | Output
-------------+-----------
6 2 | 7
7 4 6 3 9 1 |
The time complexity is optimal, but you can make your code a tiny bit more efficient:
Don't use recursion, but an iterative solution
Don't use swap, but keep the original value in memory while copying child values to their parents and only store the initial value once you have reached the appropriate slot.
Don't perform twice 2 * i: the other child node is just the next one.
Let the heapify functions take an extra argument, which can be either the current value at index i, or the replacement value for it. This saves one assignment.
Here is how that would look for two heapify functions:
void minHeapify(int arr[], int n, int i, int key) { // add key as parameter
while (true) { // iterative
int child = 2 * i + 1; // do this only for left child, and limit number of variables
if (child+1 < n && arr[child] > arr[child+1]) // get child with least value
child++; // the right child is just one index further
if (child >= n || key <= arr[child]) break;
arr[i] = arr[child]; // don't swap, just copy child value to parent
i = child; // move down
}
arr[i] = key; // finally put the original value in the correct place
}
void maxHeapify(int arr[], int n, int i, int key) { // add key as parameter
while (true) { // iterative
int child = 2 * i + 1; // do this only for left child, and limit number of variables
if (child+1 < n && arr[child] < arr[child+1]) // get child with greatest value
child++; // the right child is just one index further
if (child >= n || key >= arr[child]) break;
arr[i] = arr[child]; // don't swap, just copy child value to parent
i = child; // move down
}
arr[i] = key; // finally put the original value in the correct place
}
void buildMinHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
minHeapify(a, n, i, a[i]); // pass a[i] also
}
void buildMaxHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
maxHeapify(a, n, i, a[i]); // pass a[i] also
}
int kthsmallest(int heap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> heap[i];
buildMaxHeap(heap, k);
for (i = k; i < n; i++) {
cin >> temp;
if (temp < heap[0])
maxHeapify(heap, k, 0, temp); // pass temp
}
return heap[0];
}
int kthlargest(int heap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> heap[i];
buildMinHeap(heap, k);
for (i = k; i < n; i++) {
cin >> temp;
if (temp > heap[0])
minHeapify(heap, k, 0, temp); // pass temp
}
return heap[0];
}
In main function you could make a special case for when k == 1 or k == n, so no heap is needed, just min() or max().
One strange thing is that the challenge you link to speaks of "kth largest" while you speak of "kth smallest". Maybe you mixed up.
So here is the code when the job is to return the kth smallest. But please check the challenge whether you should not have done it for kth largest:
int main() {//kth smallest element
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, k1;
cin >> n >> k;
k1 = n - k + 1;//kth smallest element is the same as k1th largest element
if (k == 1) {
int curr, next;
cin >> curr;
for (int i = 1; i < n; i++) {
cin >> next;
curr = min(curr, next);
}
cout << curr;
} else if (k1 == 1) {
int curr, next;
cin >> curr;
for (int i = 1; i < n; i++) {
cin >> next;
curr = max(curr, next);
}
cout << curr;
} else if (k < k1) {
int *heap = new int[k];
cout << kthsmallest(heap, k, n);
} else {
int *heap = new int[k1];
cout << kthlargest(heap, k1, n);
}
return 0;
}
You're making the assumption that using a smaller heap is always the best choice. You might want to re-think that.
For example, imagine you want to select the 96th smallest number from a list of 100. If you use a heap of size 96, then you'll do:
Build a heap with 96 items. buildHeap is O(n), and in this case n is 96.
Do up to 4 insertions into a heap of 96 items. That'll be 4*log(96).
If you use a heap of size 4, then you'll do:
Build a heap with 4 items.
Do up to 96 insertions into a heap of 4 items. That'll be 96*log(4).
The first option is 96 + 4*log(96). The base-2 log of 96 is about 6.58. So the insertions will cost 26.32, for a total of 122.32.
The second option, with the smaller heap, is 4 + 96*log(4). log(4) is 2, so you end up with 4 + 196, or a total of 196.
The smaller heap is a big loser here.
In general, you want to use the larger heap when (k + (n-k)*log(k)) < ((n-k) + k*log(n-k)).
Also:
The real-world running time of the heap selection algorithm is kind of sensitive to the order in which items are presented. For example, if you're looking for 1000th smallest number in an array of 100,000, it's going to run much faster if the array is in ascending order than if it's in descending order. The reason?
Because in the ascending case, you build your initial heap with the first 1,000 items and then you never have to modify the heap again because there is none of the following items are smaller than the largest item on the heap.
But if the array is in descending order, then every item you look at will be smaller than the largest item on the heap, which means you'd be doing a heap insertion for all 99,000 remaining items.
Imagine how your code would perform if one of the test cases is a large array in descending order.
Unless you've already proven that your way of selecting which heap size to use is clearly better, you might want to consider just going with "select kth smallest," using a maxheap of size k, regardless.

How to select all possible combination of elements from a set using recursion

This is a question from hackerrank; I am trying to understand how recursion works.
The task at hand is:
Find the number of ways that a given integer, X, can be expressed
as the sum of the Nth power of unique, natural numbers.
So for example, if X = 100 and N = 2
100 = 10² = 6² + 8² = 1² + 3² + 4² + 5² + 7²
so 100 can be expressed as the square of unique natural numbers in 3
different ways, so our output is 3.
Here is my code,:
#include <cmath>
#include <iostream>
using namespace std;
int numOfSums(int x, int& n, const int k) {
int count = 0, j;
for (int i = (k + 1); (j = (int) pow(i, n)) <= x; i++) {
j = x - j;
if (j == 0)
count++;
else
count += numOfSums(j, n, i);
}
return count;
}
int main() {
int x, n;
cin >> x >> n;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
But when I input x = 100 and n = 2, it's outputting 2, not 3. What's wrong with the code?
Link to the question: https://www.hackerrank.com/challenges/the-power-sum
Your example code returns 3 when I run it using this main():
#include <iostream>
int main() {
int x = 100, n = 2;
cout << numOfSums(x, n, 0) << endl;
return 0;
}
The problem is likely that you're using double std::pow(double, int), but you're not rounding the result to nearest integer ((int) casts round down). You should add ½ before truncating:
j = static_cast<int>(pow(i, n) + 0.5)
I've used the more-C++ style of cast, which I find clearer.
It would be more efficient to implement your own equivalent of std::pow() that operates on integers. That can be recursive, too, if you want:
unsigned long pow(unsigned long x, unsigned long n)
{
return n ? x * pow(x, n-1) : 1;
}
An iterative version is more efficient (or a tail-recursive version and suitable optimizing compiler).
Reduced version, with my changes:
template<typename T>
T powi(T x, T n)
{
T r{1};
for (; n; n /= 2) {
r *= n%2 ? x : 1;
x *= x;
}
return r;
}
template<typename T>
T numOfSums(T x, T n, T i = {})
{
T count{}, j;
for (++i; (j = powi(i, n)) <= x; ++i)
count += j == x ? 1 : numOfSums(x-j, n, i);
return count;
}
#include <iostream>
int main()
{
unsigned long int x = 100, n = 2;
std::cout << numOfSums(x, n) << std::endl;
return 0;
}

Solving 5SUM in O(n^3) with strict memory limits

I need a way to solve the classic 5SUM problem without hashing or with a memory efficient way of hashing.
The problem asks you to find how many subsequences in a given array of length N have the sum equal to S
Ex:
Input
6 5
1 1 1 1 1 1
Output
6
The restrictions are:
N <= 1000 ( size of the array )
S <= 400000000 ( the sum of the subsequence )
Memory usage <= 5555 kbs
Execution time 2.2s
I'm pretty sure the excepted complexity is O(N^3). Due to the memory limitations hashing doesn't provide an actual O(1) time.
The best I got was 70 points using this code. ( I got TLE on 6 tests )
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#define MAX 1003
#define MOD 10472
using namespace std;
ifstream in("take5.in");
ofstream out("take5.out");
vector<pair<int, int>> has[MOD];
int v[MAX];
int pnt;
vector<pair<int, int>>::iterator it;
inline void ins(int val) {
pnt = val%MOD;
it = lower_bound(has[pnt].begin(), has[pnt].end(), make_pair(val, -1));
if(it == has[pnt].end() || it->first != val) {
has[pnt].push_back({val, 1});
sort(has[pnt].begin(), has[pnt].end());
return;
}
it->second++;
}
inline int get(int val) {
pnt = val%MOD;
it = lower_bound(has[pnt].begin(), has[pnt].end(), make_pair(val, -1));
if(it == has[pnt].end() || it->first != val)
return 0;
return it->second;
}
int main() {
int n,S;
int ach = 0;
int am = 0;
int rez = 0;
in >> n >> S;
for(int i = 1; i <= n; i++)
in >> v[i];
sort(v+1, v+n+1);
for(int i = n; i >= 1; i--) {
if(v[i] > S)
continue;
for(int j = i+1; j <= n; j++) {
if(v[i]+v[j] > S)
break;
ins(v[i]+v[j]);
}
int I = i-1;
if(S-v[I] < 0)
continue;
for(int j = 1; j <= I-1; j++) {
if(S-v[I]-v[j] < 0)
break;
for(int k = 1; k <= j-1; k++) {
if(S-v[I]-v[j]-v[k] < 0)
break;
ach = S-v[I]-v[j]-v[k];
rez += get(ach);
}
}
}
out << rez << '\n';
return 0;
}
I think it can be done. We are looking for all subsets of 5 items in the array arr with the correct SUM. We have array with indexes 0..N-1. Third item of those five can have index i in range 2..N-3. We cycle through all those indexes. For every index i we generate all combinations of two numbers for index in range 0..i-1 on the left of index i and all combinations of two numbers for index in the range i+1..N-1 on the right of index i. For every index i there are less than N*N combinations on the left plus on the right side. We would store only sum for every combination, so it would not be more than 1000 * 1000 * 4 = 4MB.
Now we have two sequences of numbers (the sums) and task is this: Take one number from first sequence and one number from second sequence and get sum equal to Si = SUM - arr[i]. How many combinations are there? To do it efficiently, sequences have to be sorted. Say first is sorted ascending and have numbers a, a, a, b, c ,.... Second is sorted descending and have numbers Z, Z, Y, X, W, .... If a + Z > Si then we can throw Z away, because we do not have smaller number to match. If a + Z < Si we can throw away a, because we do not have bigger number to match. And if a + Z = Si we have 2 * 3 = 6 new combinations and get rid of both a and Z. If we get sorting for free, it is nice O(N^3) algorithm.
While sorting is not for free, it is O(N * N^2 * log(N^2)) = O(N^3 * log(N)). We need to do sorting in linear time, which is not possible. Or is it? In index i+1 we can reuse sequences from index i. There are only few new combinations for i+1 - only those that involve number arr[i] together with some number from index 0..i-1. If we sort them (and we can, because there are not N*N of them, but N at most), all we need is to merge two sorted sequences. And that can be done in linear time. We can even avoid sorting completely if we sort arr at the beginning. We just merge.
For second sequence the merging does not involve adding but removing, but it is very simmilar.
The implementation seems to work, but I expect there is off by one error somewhere ;-)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
int Generate(int arr[], int i, int sums[], int N, int NN)
{
int p1 = 0;
for (int i1 = 0; i1 < i - 1; ++i1)
{
int ai = arr[i1];
for (int i2 = i1 + 1; i2 < i; ++i2)
{
sums[p1++] = ai + arr[i2];
}
}
sort(sums, sums + p1);
return p1;
}
int Combinations(int n, int sums[], int p1, int p2, int NN)
{
int cnt = 0;
int a = 0;
int b = NN - p2;
do
{
int state = sums[a] + sums[b] - n;
if (state > 0) { ++b; }
else if (state < 0) { ++a; }
else
{
int cnta = 0;
int lastA = sums[a];
while (a < p1 && sums[a] == lastA) { a++; cnta++; }
int cntb = 0;
int lastB = sums[b];
while (b < NN && sums[b] == lastB) { b++; cntb++; }
cnt += cnta * cntb;
}
} while (b < NN && a < p1);
return cnt;
}
int Add(int arr[], int i, int sums[], int p2, int N, int NN)
{
int ii = N - 1;
int n = arr[i];
int nn = n + arr[ii--];
int ip = NN - p2;
int newP2 = p2 + N - i - 1;
for (int p = NN - newP2; p < NN; ++p)
{
if (ip < NN && (ii < i || sums[ip] > nn))
{
sums[p] = sums[ip++];
}
else
{
sums[p] = nn;
nn = n + arr[ii--];
}
}
return newP2;
}
int Remove(int arr[], int i, int sums[], int p1)
{
int ii = 0;
int n = arr[i];
int nn = n + arr[ii++];
int pp = 0;
int p = 0;
for (; p < p1 - i; ++p)
{
while (ii <= i && sums[pp] == nn)
{
++pp;
nn = n + arr[ii++];
}
sums[p] = sums[pp++];
}
return p;
}
int main() {
ifstream in("take5.in");
ofstream out("take5.out");
int N, SUM;
in >> N >> SUM;
int* arr = new int[N];
for (int i = 0; i < N; i++)
in >> arr[i];
sort(arr, arr + N);
int NN = (N - 3) * (N - 4) / 2 + 1;
int* sums = new int[NN];
int combinations = 0;
int p1 = 0;
int p2 = 1;
for (int i = N - 3; i >= 2; --i)
{
if (p1 == 0)
{
p1 = Generate(arr, i, sums, N, NN);
sums[NN - 1] = arr[N - 1] + arr[N - 2];
}
else
{
p1 = Remove(arr, i, sums, p1);
p2 = Add(arr, i + 1, sums, p2, N, NN);
}
combinations += Combinations(SUM - arr[i], sums, p1, p2, NN);
}
out << combinations << '\n';
return 0;
}

Work out a solution for codality?

A zero-indexed array A consisting of N different integers is given. The array contains integers in the range [1..(N + 1)], which means that exactly one element is missing.
Your goal is to find that missing element.
Write a function:
int solution(int A[], int N);
that, given a zero-indexed array A, returns the value of the missing element.
For example, given array A such that:
A[0] = 2 A[1] = 3 A[2] = 1 A[3] = 5
the function should return 4, as it is the missing element.
Assume that:
N is an integer within the range [0..100,000];
the elements of A are all distinct;
each element of array A is an integer within the range [1..(N + 1)].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).
It doesn't work for a case that there are two elements
int solution(vector<int> &A) {
sort(A.begin(), A.end());
int missingIndex = 0;
for (int i = 0; i < A.size(); i++)
{
if ( i != A[i]-1)
{
missingIndex = i+1;
}
}
return missingIndex;
}
Since your array is zero-indexed and the numbers are from 1 to N+1, the statement should be:
if ( i != A[i]-1)
Also, you should immediately break out from the for loop after updating the missingIndex because all entries beyond the missing element shall have (i != A[i]-1)
Moreover because of sorting your solution is O(NlogN) and not O(N).
Instead you can sum all the elements in the array (using unsigned long long int) and check its difference from N(N+1)/2
You can use the simple math formula for an arithmetic progression to get the sum of all numbers from 1 to N+1. Then iterate over all the given numbers and calculate that sum. The missing element will be the difference between the two sums.
int solution(std::vector<int> &a) {
uint64_t sum = (a.size() +1 ) * (a.size() + 2) / 2;
uint64_t actual = 0;
for(int element : a) {
actual += element;
}
return static_cast<int>(sum - actual);
}
Use all the power of STL:
#include <algorithm>
#include <functional>
int solution(vector<int> &A) {
return std::accumulate(A.begin(), A.end(), (A.size()+1) * (A.size()+2) / 2, std::minus<int>());
}
This solution uses the sign of the values as a flag. It needs at worst two pass over the elements. The N(N+1)/2 solution needs exactly one pass.
int solution(vector<int> &a) {
int n = (int)a.size();
for(auto k : a)
{
int i = abs(k) - 1;
if (i != n)
a[i] = -a[i];
}
for (int i = 0; i < n; ++i)
if (a[i]>0)
return i+1;
return n+1;
}
I solved it this way and thought of posting it here for my own reference for future and for others :)
#include <cstdint>
#include <numeric>
int solution(vector<int> &A) {
uint64_t sumAll = (A.size() + 1) * (A.size() + 2) / 2;
uint64_t sumA = std::accumulate(A.begin(), A.end(), 0);
return sumAll- sumA;
}
I solve it with this solution maybe there is something better but I test it with different values and find it work fine while the other solutions gives me strange results.
as example:
std::vector<int> A = { 12,13,11,14,16 };
std::vector<int> A2 = { 112,113,111,114,116 };
int Solution(std::vector<int> &A)
{
int temp;
for (int i = 0; i < A.size(); ++i)
{
for (int j = i+1;j< A.size();++j )
{
if (A[i] > A[j])
{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
for (int i = 0; i < A.size()-1;++i)
{
if ((A[i] + 1 != A[i + 1]))
{
return (A[i] + 1);
}
if(i+1 == A.size() - 1)
return (A[i+1] + 1);
}}
Now Everything fine but if I use the array above with the methods below, I will get wrong values excepts with small numbers <10;
std::vector<int> A = { 12,13,11,14,16 };
int Solution_2(std::vector<int> &A)
{
unsigned int n = A.size() + 1;
long long int estimated = n * (n + 1) / 2;
long long int total = 0;
for (unsigned int i = 0; i < n - 1; i++) total += A[i];
return estimated - total;
}
I will get this result -45.
or this one also the same result if I use array A :
std::vector<int> A = { 12,13,11,14,16 };
int Solution_3(std::vector<int> &A)
{
uint64_t sumAll = (A.size() + 1) * (A.size() + 2) / 2;
uint64_t sumA = std::accumulate(A.begin(), A.end(), 0);
return sumAll - sumA;
}
Hope Someone explains why this happens.

Retrieving maximum value from a range in unsorted array

I have an unsorted array. I have numerous queries in which I give a range (expressed as two array indexes) and then the maximum value from that range (that is, from the specified slice of the array) has to be returned.
For example:
array[]={23,17,9,45,78,2,4,6,90,1};
query(both inclusive): 2 6
answer: 78
Which algorithm or data structure do I construct to quickly retrieve maximum value from any range. (There are a lot of queries)
EDIT:
I am using C++
I think that some preprocessing is allowed. It is Range Minimum Query problem (maximum here).
Good review of this problem at TopCoder.
Suitable data structures: Segment tree and Sqrt-decomposition:
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N int(3e4)
using namespace std;
int act[N], len, sz, res[N];
int answer(int l, int r) {
int ret = -1, i;
for (i = l; i % sz && i <= r; i++)
ret = max(ret, act[i]);
for (; i + sz <= r + 1; i += sz)
ret = max(ret, res[i / sz]);
for (; i <= r; i++)
ret = max(ret, act[i]);
return ret;
}
int main() {
int i, m;
cin >> m;
for (i = 0; ; i++) {
cin >> act[i];
if (act[i] == -1)
break;
}
len = i;
for (sz = 1; sz * sz < len; sz++);
for (int j = i + 1; j < sz * sz; j++)
act[j] = -1;
for (int i = 0; i < sz * sz; i++)
res[i / sz] = max(res[i / sz], act[i]);
for (int i = 0; i + m <= len; i++)
cout << answer(i, i + m - 1) << endl;
return 0;
}
mergesort n get the last index value of range as will me max.
array[]={23,17,9,45,78,2,4,6,90,1};
query(both inclusive): 2 6
mergesort return 6th index var (index = 1 .. n)
answer: 78
Let say this is your array array[]={23,17,9,45,78,2,4,6,90,1};
If your array is not that big, I would offer you preprocess the array and get another array like that:
{0,0} = 23; //between arr[0] and arr[0]
{0,1} = 23;
{0,2} = 23;
{0,3} = 45;
{9,9} = 1;
So your new array is going to be newArr = {23,23,23,45,....., 1}
You can find search in O(1), for example, max between 4-5 is newArr[4*array.length+5)-1];
In total, for n queries you will have O(n).
The space is if you have 10000(10^4) integer, then your newArr = 10^8 * 4B = 400MB, so if you have more than 10000 int, then this wouldnt work
EDIT: I thought of something but it is same as algorithm in Topcoder that MBo mentions.