Infinite array problem in for q number of queries - c++

Given an array, "A" of integers and you have also defined the new array"B"as a concatenation of
array"A" for an infinite number of times.
For example,if the given array"A"is[1,2,3]then,infinite array“B”is[1,2,3,1,2,3,1,2,3 ........
Now you are given q queries, each query consists of two integers"L" and"R"(1-based indexing).
Your task is to find the sum of the subarray from index"L" to"R"(both inclusive)in the infinite array "B" for each query.
Note:
The value of the sum can be very large,return the answer as modulus 10^9+7.
Input Format
The first line of input contains a single integer T, representing the number of test cases
or queries to be run.
Then the test cases follow.
The first line of each test case contains a single integer N, denoting the size of the
array"A".
The second line of each test case contains N single space-separated integers, elements of
the array"A".
The third line of each test case contains a single integer Q, denoting the number of
queries.
Then each of the Q lines of each test case contains two single space-separated integers L,
and R denote the left and the right index of the infinite array"B" whose sum is to be
returned.
I have come up with an approach that doesn't think is the optimal solution for this. I have used two pointer approach in this.
#include <iostream>
#include <vector>
vector<int> sumInRanges(vector<int> &arr, int n, vector<vector<long long>> &queries, int q) {
// Write your code here
vector<int> res;
for(int i = 0; i < q; i++){
int sum = 0;
int start = queries[i][0];
int end = queries[i][1];
while( start <= end ){
if(start < arr.size()){
sum += arr[start - 1];
}
else{
int mod = start % arr.size();
sum += arr[mod - 1];
}
}
res.push_back(sum);
}
return res;
}

Hint: think where you do the same things
Suppose A=[1,2,3], L=2, R=14
Your approach iterates over
2,3, 1,2,3, 1,2,3, 1,2,3, 1,2
see, how many times you iterate over the whole array?
instead, calculate sum(A) ONCE
then, calculate how many times it's used in the query (something like floor(R/len(A)) - ceil(L/len(A)))
multiply them
iterate ONCE to find missing sums (left from L%len(A) to len(A) and right from beginning to R%len(A))
And don't forget about the modulo 1e9+7
If len(A) and q get huge - save partial sums to beginning and partial sums till end once
And then retrieve them each query in constant time

Related

Sum of infinite array fails one test case

Problem Statement:
Given an array “A” of N integers and you have also defined the new
array “B” as a concatenation of array “A” for an infinite number of
times. For example, if the given array “A” is [1,2,3] then, infinite
array “B” is [1,2,3,1,2,3,1,2,3,.......]. Now you are given Q queries,
each query consists of two integers “L“ and “R”. Your task is to find
the sum of the subarray from index “L” to “R” (both inclusive) in the
infinite array “B” for each query.
vector<int> sumInRanges(vector<int> &arr, int n, vector<vector<long long>> &queries, int q) {
vector<int> ans;
for(int i=0; i<q; i++){
int l = queries[i][0];
int r = queries[i][1];
int sum = 0;
for(int j=l-1; j<r; j++){
sum += arr[j%n];
}
ans.push_back(sum);
}
return ans;
}
One test case is failing. Could someone suggest the edit required?
Good I've found link to your actual problem.
Take a look on note:
Sum Of Infinite Array
Note :
The value of the sum can be very large, return the answer as modulus 10^9+7.
....
Constraints :
1 <= T <= 100
1 <= N <= 10^4
1 <= A[i] <= 10^9
1 <= Q <= 10^4
1 <= L <= R <= 10^18
Time Limit: 1sec
So basically your code have problem with integer overflow.
Your implementation is to simple. You have to leverage fact that this infinitive array has a period otherwise your code never meets time requirement. You do not have to calculate sum of the all indexes, you can skip a lot and calculate correction using multiplication (modulo).
Your solution takes time proportional to l - r because it tries every number.
But this is unnecessary, as there are n identical periods that you can sum in a single go. So the running time can be made proportional to the length of A instead. (Find the multiple of the length just above or on l and the multiple just below r.)
E.g. to sum from 10 to 27 inclusive, use
1231231231|231231231231231231|23123123... = 1231231231|23+4x123+1|23123123...

Find the character at the `k`th location in the infinite string

I am trying to solve a problem:
Given two strings, s and t, we can form a string x of infinite length, as:
a. Append s to x 1 time;
b. Append t to x 2 times;
c. Append s to x 3 times;
d. Append t to x 4 times;
and so on...
Given k, find the kth character (1 indexed) in the resultant infinite string x.
For e.g., if s = a, t = bc and k = 4, then output: b (x=abcbc). s and t can contain anywhere from 1 to 100 characters, while 1<=k<=10^16.
The brute force way of actually constructing string x is trivial but too slow. How do I optimize it further?
In C++, the brute force solution would look like this:
#include <iostream>
using namespace std;
int main() {
int repeat=1, k=4;
string s="a", t="bc", x;
bool appendS=true;
while(x.size()<k) {
for(int i=1; i<=repeat; i++)
if(appendS) x+=s;
else x+=t;
appendS=!appendS;
repeat++;
}
cout<<x[k-1];
return 0;
}
But how do I optimize it, given huge k?
The string looks like
sttsssttttsssssttttttssssssstttttttt...
Group the string into substrings like
(stts)(ssttttss)(sssttttttsss)(ssssttttttttssss)(sssss...
Let
len(s) = a
len(t) = b
len(s+t) = c
Group 1: stts -> length = 2*c.
Group 2: ssttttss -> length = 4*c.
Group 3: sssttttttsss -> length = 6*c.
Continuing the pattern, it is easy to see that the length of ith group will be 2*i*c.
Let the kth character be in group n.
Total length of first n groups =
2*c + 4*c + 6*c .... + 2*n*c = (2*c)*(1+2+3...+n) = c*n*(n+1)
Since total length of n groups has to be greater than or equal to k,
c*n*(n+1) >= k
n*(n+1) >= k/c
Finding the largest value of n that satisfies this inequality is a trivial task. Now, the nth group looks something like
ss...(n times) + tttt...(2*n times) + ss...(n times)
Now, you just need to find the position of k mod n in this block, which is a simple task.
The search position is located at the nth append, where n is calculated for the last integer where this sum inequality holds, where l1 and l2 are the two strings lengths:
Hence, the search position is at the nth append, at the mod(n+1,2)+1 string, in the Delta k character of that string.
Explanation:
The sum is the addition of all lengths. Since you know all the substrings, you know the whole sum. And since both are integer algebraic expression, you have to do a little linear search over that, to find that integer n, as in any simple integer equation.
Having the nth append number, and the sum, the position is trivially obtained as Delta k.
Moreover, note that Delta k is a closed expression. You do not need any loop to calculate it, just to evaluate, since the sums of the i terms are the sum of the first floor(n/2) even and the first floor(n/2)+1 odd integers.

A problem of taking combination for set theory

Given an array A with size N. Value of a subset of Array A is defined as product of all numbers in that subset. We have to return the product of values of all possible non-empty subsets of array A %(10^9+7).
E.G. array A {3,5}
` Value{3} = 3,
Value{5} = 5,
Value{3,5} = 5*3 = 15
answer = 3*5*15 %(10^9+7).
Can someone explain the mathematics behind the problem. I am thinking of solving it by combination to solve it efficiently.
I have tried using brute force it gives correct answer but it is way too slow.
Next approach is using combination. Now i think that if we take all the sets and multiply all the numbers in those set then we will get the correct answer. Thus i have to find out how many times a number is coming in calculation of answer. In the example 5 and 3 both come 2 times. If we look closely, each number in a will come same number of times.
You're heading in the right direction.
Let x be an element of the given array A. In our final answer, x appears p number of times, where p is equivalent to the number of subsets of A possible that include x.
How to calculate p? Once we have decided that we will definitely include x in our subset, we have two choices for the rest N-1 elements: either include them in set or do not. So, we conclude p = 2^(N-1).
So, each element of A appears exactly 2^(N-1) times in the final product. All remains is to calculate the answer: (a1 * a2 * ... * an)^p. Since the exponent is very large, you can use binary exponentiation for fast calculation.
As Matt Timmermans suggested in comments below, we can obtain our answer without actually calculating p = 2^(N-1). We first calculate the product a1 * a2 * ... * an. Then, we simply square this product n-1 times.
The corresponding code in C++:
int func(vector<int> &a) {
int n = a.size();
int m = 1e9+7;
if(n==0) return 0;
if(n==1) return (m + a[0]%m)%m;
long long ans = 1;
//first calculate ans = (a1*a2*...*an)%m
for(int x:a){
//negative sign does not matter since we're squaring
if(x<0) x *= -1;
x %= m;
ans *= x;
ans %= m;
}
//now calculate ans = [ ans^(2^(n-1)) ]%m
//we do this by squaring ans n-1 times
for(int i=1; i<n; i++){
ans = ans*ans;
ans %= m;
}
return (int)ans;
}
Let,
A={a,b,c}
All possible subset of A is ={{},{a},{b},{c},{a,b},{b,c},{c,a},{a,b,c,d}}
Here number of occurrence of each of the element are 4 times.
So if A={a,b,c,d}, then numbers of occurrence of each of the element will be 2^3.
So if the size of A is n, number of occurrence of eachof the element will be 2^(n-1)
So final result will be = a1^p*a2^pa3^p....*an^p
where p is 2^(n-1)
We need to solve x^2^(n-1) % mod.
We can write x^2^(n-1) % mod as x^(2^(n-1) % phi(mod)) %mod . link
As mod is a prime then phi(mod)=mod-1.
So at first find p= 2^(n-1) %(mod-1).
Then find Ai^p % mod for each of the number and multiply with the final result.
I read the previous answers and I was understanding the process of making sets. So here I am trying to put it in as simple as possible for people so that they can apply it to similar problems.
Let i be an element of array A. Following the approach given in the question, i appears p number of times in final answer.
Now, how do we make different sets. We take sets containing only one element, then sets containing group of two, then group of 3 ..... group of n elements.
Now we want to know for every time when we are making set of certain numbers say group of 3 elements, how many of these sets contain i?
There are n elements so for sets of 3 elements which always contains i, combinations are (n-1)C(3-1) because from n-1 elements we can chose 3-1 elements.
if we do this for every group, p = [ (n-1)C(x-1) ] , m going from 1 to n. Thus, p= 2^(n-1).
Similarly for every element i, p will be same. Thus we get
final answer= A[0]^p *A[1]^p...... A[n]^p

Dynamic Programming w/ 1D array USACO Training: Subset Sums

While working through the USACO Training problems, I found out about Dynamic Programming. The first training problem that deals with this concept is a problem called Subset Sums.
The Problem Statement Follows:
For many sets of consecutive integers from 1 through N (1 <= N <= 39), one can partition the set into two sets whose sums are identical.
For example, if N=3, one can partition the set {1, 2, 3} in one way so that the sums of both subsets are identical:
{3} and {1,2}
This counts as a single partitioning (i.e., reversing the order counts as the same partitioning and thus does not increase the count of partitions).
If N=7, there are four ways to partition the set {1, 2, 3, ... 7} so that each partition has the same sum:
{1,6,7} and {2,3,4,5}
{2,5,7} and {1,3,4,6}
{3,4,7} and {1,2,5,6}
{1,2,4,7} and {3,5,6}
Given N, your program should print the number of ways a set containing the integers from 1 through N can be partitioned into two sets whose sums are identical. Print 0 if there are no such ways.
Your program must calculate the answer, not look it up from a table.
INPUT FORMAT
The input file contains a single line with a single integer representing N, as above.
SAMPLE INPUT (file subset.in)
7
OUTPUT FORMAT
The output file contains a single line with a single integer that tells how many same-sum partitions can be made from the set {1, 2, ..., N}. The output file should contain 0 if there are no ways to make a same-sum partition.
SAMPLE OUTPUT (file subset.out)
4
After much reading, I found an algorithm that was explained to be a variation of the 0/1 knapsack problem. I implemented it in my code, and I solved the problem. However, I have no idea how my code works or what is going on.
*Main Question: I was wondering if someone could explain to me how the knapsack algorithm works, and how my program could possibly be implementing this in my code?
My code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fin("subset.in");
ofstream fout("subset.out");
long long num=0, ways[800]={0};
ways[0]=1;
cin >> num;
if(((num*(num+1))/2)%2 == 1)
{
fout << "0" << endl;
return 0;
}
//THIS IS THE BLOCK OF CODE THAT IS SUPPOSED TO BE DERIVED FROM THE
// O/1 KNAPSACK PROBLEM
for (int i = 1; i <= num; i++)
{
for (int j = (num*(num+1))/2 - i; j >= 0; --j)
{
ways[j + i] += ways[j];
}
}
fout << ways[(num*(num+1))/2/2]/2 << endl;
return 0;
}
*note: Just to emphasize, this code does work, I just would like an explanation why it works. Thanks :)
I wonder why numerous sources could not help you.
Trying one more time with my ugly English:
ways[0]=1;
there is a single way to make empty sum
num*(num+1))/2
this is MaxSum - sum of all numbers in range 1..num (sum of arithmetic progression)
if(((num*(num+1))/2)%2 == 1)
there is no chance to divide odd value into two equal parts
for (int i = 1; i <= num; i++)
for every number in range
for (int j = (num*(num+1))/2 - i; j >= 0; --j)
ways[j + i] += ways[j];
sum j + i might be built using sum j and item with value i.
For example, consider that you want make sum 15.
At the first step of outer cycle you are using number 1, and there is ways[14] variants to make this sum.
At the second step of outer cycle you are using number 2, and there is ways[13] new variants to make this sum, you have to add these new variants.
At the third step of outer cycle you are using number 3, and there is ways[12] new variants to make this sum, you have to add these new variants.
ways[(num*(num+1))/2/2]/2
output number of ways to make MaxSum/2, and divide by two to exclude symmetric variants ([1,4]+[2,3]/[2,3]+[1,4])
Question for self-thinking: why inner cycle goes in reverse direction?

calculation of permutation sequence

I am working on below problem and post code I am debugging and the problem statement. Actually I tried to find a few reference solutions, and all are similar without too much explanation. If anyone could help to explain how below logic works, it will be great. I am confused especially by the loop of "for(i=0,k--;i
The set [1,2,3,…,n] contains a total of n! unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
Code reference,
#include <iostream>
using namespace std;
string getPermutation(int n, int k) {
int i,j,f=1;
// left part of s is partially formed permutation, right part is the leftover chars.
string s(n,'0');
for(i=1;i<=n;i++){
f*=i;
s[i-1]+=i; // make s become 1234...n
}
for(i=0,k--;i<n;i++){
f/=n-i;
j=i+k/f; // calculate index of char to put at s[i]
char c=s[j];
// remove c by shifting to cover up (adjust the right part).
for(;j>i;j--)
s[j]=s[j-1];
k%=f;
s[i]=c;
}
return s;
}
int main(int argc, const char * argv[])
{
// insert code here...
std::cout << getPermutation(4, 5) << endl;
return 0;
}
Post another implementation which is more clear to read,
def kthperm(S, k): # nonrecursive version
P = []
while S != []:
f = factorial(len(S)-1)
i = int(floor(k/f))
x = S[i]
k = k%f
P.append(x)
S = S[:i] + S[i+1:]
return P
The problem statement asks for the Kth permutation of N elements, in the lexical ordering of the permutations.
The code implements a very nice algorithm that generates the elements of the Kth permutation directly, in order, like this (pseudo-code):
GenerateKthPermutation(Set elements, int k)
{
if (elements.size()==1)
{
output(elements.getOnlyElement());
return;
}
int n = elements.size();
//there are n! permutations of elements
//no matter which one we choose as the _first_ element, there
//will be (n-1)! permutations of the remaining elements.
//The complete lexical ordering of permutations consists of:
//(n-1)! permutations that start with the smallest element, then
//(n-1)! permutations that start with the second smallest element, then
//(n-1)! permutations that start with the 3rd smallest element, etc.
//so the FIRST element in the (0-indexed) kth permutation, is the
//(0-indexed) floor(k/(n-1)!)th-largest element
int j = floor((k-1)/(n-1)!); //k-1, because the parameter is 1-indexed
//removeJthLargest(0) removes and returns the smallest element
//removeJthLargest(1) removes and returns the second-smallest
//etc.
output(elements.removeJthLargest(j));
//now output the correct permutation of remaining elements.
//we've skipped j*(n-1)! permutations, so subtract that from k
k -= j*(n-1)!;
//remember elements is 1 smaller now.
//in real life you would iterate here instead of recursing
GenerateKthPermutation(elements, k);
}
I hope that makes things clear. To specifically answer your question in comments:
The original logic uses a sorted string to store the set of elements. the part that says "remove c by shifting..." is the part where I say "elements.removeJthLargest(j)". It removes the proper element from the string and shifts the remaining ones to make a new, smaller, but still-sorted string.