XOR of N elements after M timestamps of modification in them - bit-manipulation

There are N elements (numbered 1 to N). All are Zero initially. There
are M timestamps. In each timestamp, all the elements numbered between
L and R (both inclusive) increased by P. Find XOR of all elements
after M timestamps.
Input Format
The first line of the input contains a single integer T denoting the
number of test cases. The description of T test cases follows. The
first line contains two space-separated integers N, M. M lines follow.
The ith of these M lines contains three space-separated integers L, R,
P, describing the ith timestamp.
Constraints
1 < T < 100
1 < N < 1e16
0 < M < 1e4
1 < L < R < N
0 < P < 1e9
Sum of M over all test cases do not exceed 1e5
My approach
while(t--){
long long n,m;
cin>>n>>m;
long long a[n+1]={0};
while(m--){
ll x,y,p;
cin>>x>>y>>p;
for(int i=x;i<=y;i++)
a[i]=a[i]+p;
}
long long ans=0;
for(int i=1;i<=n;i++)
ans=ans^a[i];
cout<<ans<<"\n";
}
I can only come up with a bruteforce idea by which it seems impossible to solve because the constraints are too large.
How can I answer each test case in O(1) time. Thet Time limit for this question is only 1 sec.

The N elements can be viewed as members of an array.
If there are an even number of contiguous elements with the same value, the XOR of all these elements is zero.
If there are an odd number of contiguous elements with the same value X, the XOR of all these elements is X.
A solution to this problem is to iterate over the array, keeping track of how many repeated values of X there are prior to a change in value, and XOR'ing X to the running result if there were an odd number of repeats.
This can be computed without having to actually construct the array, nor loop over each element, by considering only the specified L and R indices from the input, which indicate the places where an array value may differ from its adjacent neighbor.
Here's an implementation in Python, which reads the input from stdin.
import sys
from collections import defaultdict
def getline():
return sys.stdin.readline().rstrip()
T = int(getline())
for _ in range(T):
N, M = map(int, getline().split())
lookup = defaultdict(int)
for _ in range(M):
L, R, P = map(int, getline().split())
lookup[L] += P
lookup[R + 1] -= P
lookup[N + 1] = 0
result = 0
X = 0
last_idx = 1
for idx in sorted(lookup):
count = idx - last_idx
if count & 1:
result ^= X
X += lookup[idx]
last_idx = idx
print(result)

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...

Intuition behind storing the remainders?

I am trying to solve a question on LeetCode.com:
Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer. For e.g., if [23, 2, 4, 6, 7], k=6, then the output should be True, since [2, 4] is a continuous subarray of size 2 and sums up to 6.
I am trying to understand the following solution:
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int n = nums.size(), sum = 0, pre = 0;
unordered_set<int> modk;
for (int i = 0; i < n; ++i) {
sum += nums[i];
int mod = k == 0 ? sum : sum % k;
if (modk.count(mod)) return true;
modk.insert(pre);
pre = mod;
}
return false;
}
};
I understand that we are trying to store: 0, (a/k), (a+b)/k, (a+b+c)/k, etc. into the hashSet (where k!=0) and that we do that in the next iteration since we want the subarray size to be at least 2.
But, how does this guarantee that we get a subarray whose elements sum up to k? What mathematical property guarantees this?
The set modk is gradually populated with all sums (considered modulo k) of contiguous sub-arrays starting at the beginning of the array.
The key observation is that:
a-b = n*k for some natural n iff
a-b ≡ 0 mod k iff
a ≡ b mod k
so if a contiguous sub-array nums[i_0]..nums[i_1], sums up to 0 modulo k, then the two sub-arrays nums[0]..nums[i_0] and nums[i_0 + 1]..nums[i_1] have the same sum modulo k.
Thus it's enough if two distinct sub-arrays starting at the beginning of the array have the same sum, modulo k.
Luckily, there are only k such values, so you only need to use a set of size k.
Some nitpicks:
if n > k, you're going to have an appropriate sub-array anyway (the pigeon-hole principle), so the loop will actually never iterate more than k+1 times.
There should not be any sort of class involved here, that makes no sense.
contiguous, not continuous. Arrays and sub-arrays are discrete and can't be continuous...
module base k of sum is equivalent to the module k of sum of the modules base k
(a+b)%k = (a%k + b%k) % k
(23 + 2) % 6 = 1
( (23%6) + (2%6) ) % 6 = (5 + 2) % 6 = 1
modk stores all modules that you calculated iteratively. If at iteration i you get a repeated module calculated at i-m that means that you added a subsequence of m elements which sum is multiple of k
i=0 nums[0] = 23 sum = 23 sum%6 = 5 modk = [5]
i=1 nums[1] = 2 sum = 25 sum%6 = 1 modk = [5, 1]
i=2 nums[2] = 4 sum = 29 sum%6 = 5 5 already exists in modk (4+2)%6 =0

Finding number of subsets of an array that add up to a multiple of a specific number

I have an array A of length N of negative as well as positive integers. I need to count the number of subsets in this array which add up to a multiple of a number M (or 0 (mod M))
For example:
Let A = {1,2,8,4,5}, M = 9,
Then, there are 4 such subsets:
{}: Empty set, corresponding to the multiple 0,
{1,8}: corresponding to the multiple 9,
{4,5}: corresponding to the multiple 9
{1,8,4,5}: corresponding to the multiple 18.
I thought of generating all possible multiples and then applying dynamic programming subset sum, but the constraints won't allow me that.
Constraints:
1 =< N <= 10^5,
1 =< M <= 100,
-10^9 =< each entry of array <=10^9
What should be my approach for this sort of problem?
You can solve this problem by dynamic programming, albeit extensive for large M and fast for small M. For each j satisfying 0 <=j <= M-1, and each integer k satisfying 0 < k <= N, let f(k,j) be the number of subsets of array elements between 1 and k that add up to give a sum of j mod M. Then to extend the counter f(k,j) to f(k+1,j') for all j' you just need to take the (k+1)th element X in your sequence and set f(k+1,j') = f(k,j') + f(k,j' - X mod M). When you iterate over all j satisfying 0 <= j <= M-1 for each k and then successively iterate over all k satisfying 0 <= k <= N, you will get your answer at f(N,0). Total complexity is O(MN), which for small M is basically linear in N, optimal.

Maximum subset which has no sum of two divisible by K

I am given the set {1, 2, 3, ... ,N}. I have to find the maximum size of a subset of the given set so that the sum of any 2 numbers from the subset is not divisible by a given number K. N and K can be up to 2*10^9 so i need a very fast algorithm. I only came up with an algorithm of complexity O(K), which is slow.
first calculate all of the set elements mod k.and solve simple problem:
find the maximum size of a subset of the given set so that the sum of any 2 numbers from the subset is not equal by a given number K.
i divide this set to two sets (i and k-i) that you can not choose set(i) and set(k-i) Simultaneously.
int myset[]
int modclass[k]
for(int i=0; i< size of myset ;i++)
{
modclass[(myset[i] mod k)] ++;
}
choose
for(int i=0; i< k/2 ;i++)
{
if (modclass[i] > modclass[k-i])
{
choose all of the set elements that the element mod k equal i
}
else
{
choose all of the set elements that the element mod k equal k-i
}
}
finally you can add one element from that the element mod k equal 0 or k/2.
this solution with an algorithm of complexity O(K).
you can improve this idea with dynamic array:
for(int i=0; i< size of myset ;i++)
{
x= myset[i] mod k;
set=false;
for(int j=0; j< size of newset ;j++)
{
if(newset[j][1]==x or newset[j][2]==x)
{
if (x < k/2)
{
newset[j][1]++;
set=true;
}
else
{
newset[j][2]++;
set=true;
}
}
}
if(set==false)
{
if (x < k/2)
{
newset.add(1,0);
}
else
{
newset.add(0,1);
}
}
}
now you can choose with an algorithm of complexity O(myset.count).and your algorithm is more than O(myset.count) because you need O(myset.count) for read your set.
complexity of this solution is O(myset.count^2),that you can choose algorithm depended your input.with compare between O(myset.count^2) and o(k).
and for better solution you can sort myset based on mod k.
I'm assuming that the set of numbers is always 1 through N for some N.
Consider the first N-(N mod K) numbers. The form floor(N/K) sequences of K consecutive numbers, with reductions mod K from 0 through K-1. For each group, floor(K/2) have to be dropped for having a reduction mod K that is the negation mod K of another subset of floor(K/2). You can keep ceiling(K/2) from each set of K consecutive numbers.
Now consider the remaining N mod K numbers. They have reductions mod K starting at 1. I have not worked out the exact limits, but if N mod K is less than about K/2 you will be able to keep all of them. If not, you will be able to keep about the first ceiling(K/2) of them.
==========================================================================
I believe the concept here is correct, but I have not yet worked out all the details.
==========================================================================
Here is my analysis of the problem and answer. In what follows |x| is floor(x). This solution is similar to the one in #Constantine's answer, but differs in a few cases.
Consider the first K*|N/K| elements. They consist of |N/K| repeats of the reductions modulo K.
In general, we can include |N/K| elements that are k modulo K subject to the following limits:
If (k+k)%K is zero, we can include only one element that is k modulo K. That is the case for k=0 and k=(K/2)%K, which can only happen for even K.
That means we get |N/K| * |(K-1)/2| elements from the repeats.
We need to correct for the omitted elements. If N >= K we need to add 1 for the 0 mod K elements. If K is even and N>=K/2 we also need to add 1 for the (K/2)%K elements.
Finally, if M(N)!=0 we need to add a partial or complete copy of the repeat elements, min(N%K,|(K-1)/2|).
The final formula is:
|N/K| * |(K-1)/2| +
(N>=K ? 1 : 0) +
((N>=K/2 && (K%2)==0) ? 1 : 0) +
min(N%K,|(K-1)/2|)
This differs from #Constantine's version in some cases involving even K. For example, consider N=4, K=6. The correct answer is 3, the size of the set {1, 2, 3}. #Constantine's formula gives |(6-1)/2| = |5/2| = 2. The formula above gets 0 for each of the first two lines, 1 from the third line, and 2 from the final line, giving the correct answer.
formula is
|N/K| * |(K-1)/2| + ost
ost =
if n<k:
ost =0
else if n%k ==0 :
ost =1
else if n%k < |(K-1)/2| :
ost = n%k
else:
ost = |(K-1)/2|
where |a/b|
for example |9/2| = 4 |7/2| = 3
example n = 30 , k =7 ;
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
1 2 3 |4| 5 6 7. - is first line .
8 9 10 |11| 12 13 14 - second line
if we getting first 3 number in each line we may get size of this subset. also we may adding one number from ( 7 14 28)
getting first 3 number (1 2 3) is a number |(k-1)/2| .
a number of this line is |n/k| .
if there is not residue we may add one number (for example last number).
if residue < |(k-1)/2| we get all number in last line
else getting |(K-1)/2|.
thanks for exception case.
ost = 0 if k>n
n,k=(raw_input().split(' '))
n=int(n)
k=int(k)
l=[0 for x in range(k)]
d=[int(x) for x in raw_input().split(' ')]
flag=0
for x in d:
l[x%k]=l[x%k]+1
sum=0
if l[0]!=0:
sum+=1
if (k%2==0):
sum+=1
if k==1:
print 1
elif k==2:
print 2
else:
i=1
j=k-1
while i<j:
sum=sum+(l[i] if l[i]>=l[j] else l[j])
i=i+1
j=j-1
print sum
This is explanation to ABRAR TYAGI and amin k's solution.
The approach to this solution is:
Create an array L with K buckets and group all the elements from the
input array D into the K buckets. Each bucket L[i] contains D's elements such that ( element % K ) = i.
All the elements that are individually divisible by K are in L[0]. So
only one of these elements (if any) can belong in our final (maximal)
subset. Sum of any two of these elements is divisible by K.
If we add an element from L[i] to an element in L[K-i] then the sum is divisible by K. Hence we can add elements from only one of these buckets to
our final set. We pick the largest bucket.
Code:
d is the array containing the initial set of numbers of size n. The goal of this code is to find the count of the largest subset of d such that the sum of no two integers is divisible by 2.
l is an array that will contain k integers. The idea is to reduce each (element) in array d to (element % k) and save the frequency of their occurrences in array l.
For example, l[1] contains the frequency of all elements % k = 1
We know that 1 + (k-1) % k = 0 so either l[1] or l[k-1] have to be discarded to meet the criteria that sum of no two numbers % k should be 0.
But as we need the largest subset of d, we choose the larger of l[1] and l[k-1]
We loop through array l such that for (i=1; i<=k/2 && i < k-i; i++) and do the above step.
There are two outliers. The sum of any two numbers in the l[0] group % k = 0. So add 1 if l[0] is non-zero.
if k is even, the loop does not handle i=k/2, and using the same logic as above increment the count by one.

Find two missing numbers

We have a machine with O(1) memory and we want to pass n numbers (one by one) in the first pass, and then we exclude the two numbers and we will pass n-2 numbers to the machine.
write an algorithm that finds missing numbers.
It can be done with O(1) memory.
You only need a few integers to keep track of some running sums. The integers do not require log n bits (where n is the number of input integers), they only require 2b+1 bits, where b is the number of bits in an individual input integer.
When you first read the stream add all the numbers and all of their squares, i.e. for each input number, n, do the following:
sum += n
sq_sum += n*n
Then on the second stream do the same thing for two different values, sum2 and sq_sum2. Now do the following maths:
sum - sum2 = a + b
sq_sum - sq_sum2 = a^2 + b^2
(a + b)(a + b) = a^2 + b^2 + 2ab
(a + b)(a + b) - (a^2 + b^2) = 2ab
(sum*sum - sq_sum) = 2ab
(a - b)(a - b) = a^2 + b^2 - 2ab
= sq_sum - (sum*sum - sq_sum) = 2sq_sum - sum*sum
sqrt(2sq_sum - sum*sum) = sqrt((a - b)(a - b)) = a - b
((a + b) - (a - b)) / 2 = b
(a + b) - b = a
You need 2b+1 bits in all intermediate results because you are storing products of two input integers, and in one case multiplying one of those values by two.
Assuming the numbers are ranging from 1..N and 2 of them are missing - x and y, you can do the following:
Use Gauss formula: sum = N(N+1)/2
sum - actual_sum = x + y
Use product of numbers: product = 1*2..*N = N!
product - actual_product = x * y
Resolve x,y and you have your missing numbers.
In short - go through the array and sum up each element to get the actual_sum, multiply each element to get actual_product. Then resolve the two equations for x an y.
It cannot be done with O(1) memory.
Assume you have a constant k bits of memory - then you can have 2^k possible states for your algorithm.
However - input is not limited, and assume there are (2^k) + 1 possible answers for (2^k) + 1 different problem cases, from piegeonhole principle, you will return the same answer twice for 2 problems with different answers, and thus your algorithm is wrong.
The following came to my mind as soon as I finished reading the question. But the answers above suggest that it is not possible with O(1) memory or that there should be a constraint on the range of numbers. Tell me if my understanding of the question is wrong. Ok, so here goes
You have O(1) memory - which means you have constant amount of memory.
When the n numbers are passed to you 1st time, just keep adding them in one variable and keep multiplying them in another. So at the end of 1st pass you have the sum and product of all the numbers in 2 variables S1 and P1. You have used 2 variable till now (+1 if you reading the numbers in memory).
When the (n-2) numbers are passed to you the second time, do the same. Store the sum and product of the (n-2) numbers in 2 other variables S2 and P2. You have used 4 variables till now (+1 if you reading the numbers in memory).
If the two missing numbers are x and y, then
x + y = S1 - S2
x*y = P1/P2;
You have two equations in two variables. Solve them.
So you have used a constant amount of memory (independent of n).
void Missing(int arr[], int size)
{
int xor = arr[0]; /* Will hold xor of all elements */
int set_bit_no; /* Will have only single set bit of xor */
int i;
int n = size - 2;
int x = 0, y = 0;
/* Get the xor of all elements in arr[] and {1, 2 .. n} */
for(i = 1; i < size; i++)
xor ^= arr[i];
for(i = 1; i <= n; i++)
xor ^= i;
/* Get the rightmost set bit in set_bit_no */
set_bit_no = xor & ~(xor-1);
/* Now divide elements in two sets by comparing rightmost set
bit of xor with bit at same position in each element. */
for(i = 0; i < size; i++)
{
if(arr[i] & set_bit_no)
x = x ^ arr[i]; /*XOR of first set in arr[] */
else
y = y ^ arr[i]; /*XOR of second set in arr[] */
}
for(i = 1; i <= n; i++)
{
if(i & set_bit_no)
x = x ^ i; /*XOR of first set in arr[] and {1, 2, ...n }*/
else
y = y ^ i; /*XOR of second set in arr[] and {1, 2, ...n } */
}
printf("\n The two repeating missing elements are are %d & %d ", x, y);
}
Please look at the solution link below. It explains an XOR method.
This method is more efficient than any of the methods explained above.
It might be the same as Victor above, but there is an explanation as to why this works.
Solution here
Here is the simple solution which does not require any quadratic formula or multiplication:
Let say B is the sum of two missing numbers.
The set of two missing numbers will be one from:
(1,B-1),(2,B-1)...(B-1,1)
Therefore, we know that one of those two numbers will be less than or equal to the half of B.
We know that we can calculate the B (sum of both missing number).
So, once we have B, we will find the sum of all numbers in the list which are less than or equal to B/2 and subtract that from the sum of (1 to B/2) to get the first number. And then, we get the second number by subtracting first number from B. In below code, rem_sum is B.
public int[] findMissingTwoNumbers(int [] list, int N){
if(list.length == 0 || list.length != N - 2)return new int[0];
int rem_sum = (N*(N + 1))/2;
for(int i = 0; i < list.length; i++)rem_sum -= list[i];
int half = rem_sum/2;
if(rem_sum%2 == 0)half--; //both numbers cannot be the same
int rem_half = getRemHalf(list,half);
int [] result = {rem_half, rem_sum - rem_half};
return result;
}
private int getRemHalf(int [] list, int half){
int rem_half = (half*(half + 1))/2;
for(int i = 0; i < list.length; i++){
if(list[i] <= half)rem_half -= list[i];
}
return rem_half;
}