Problem Link-https://www.codechef.com/ZCOPRAC/problems/ZCO14004
Please explain your approach with code
Problem Link-https://www.codechef.com/ZCOPRAC/problems/ZCO14004
Please explain your approach with code
why am I getting the wrong answer although my output is correct?! here's the Q:https://www.codechef.com/problems/TLG my code(c):
#include <stdio.h>
#include <stdlib.h>
int r;
int main()
{
scanf("%d",&r);
int sc[r][4],i,max1=0,max2=0;
for(i=0;i<r;i++)
{
scanf("%d",&sc[i][0]);scanf("%d",&sc[i][1]);
if(sc[i][0]>sc[i][1])
{
sc[i][2]=(sc[i][0]-sc[i][1]);
sc[i][3]=0;}
else
{
sc[i][3]=(sc[i][1]-sc[i][0]);
sc[i][2]=0;}
}
max1=sc[0][2];
max2=sc[0][3];
for (i=0;i<r;i++)
{
if(sc[i][2]>max1)
{
max1=sc[i][2];
}
if(sc[i][3]>max2)
{
max2=sc[i][3];
}
}
if(max1>max2)
{printf("\n%d",1);printf(" %d",max1);}
else
{printf("\n%d",2);printf(" %d",max2);}
return 0;
}
Here's the Problem
Went through the editorial, it said something like grundy theorem and all which I didn't follow.
Tell me some possible approach or a dummy solution.
In editorial of SNAKEEAT problem, can anyone please explain the offline approach in more detail.
I am not getting the logic of this approach, what we are trying to achieve by calculating prefix and significance of the condition (prefix>prev) and also explain why this approach is working.
Please help me too, i had made this code for scoring 100 points as per the given constraints. I keep getting WA in some test cases, and i am not able to identify the case. Please help me
https://www.codechef.com/viewsolution/14080761
Thank you.
Author:Ankit Srivastava
Tester:Kevin Atienza and Gedi Zheng
Editorialist:Kevin Atienza
String processing, string polynomial hashing
You are given a string $S$, and you have to answer $Q$ queries. Each query consists of four integers $(i,j,k,l)$, and you need to tell whether the substring from the $k$th position to the $l$th position is a palindrome assuming the substring from the $i$th position to the $j$th position is reversed temporarily (i.e. reversals are only applied per query and do not persist for further queries).
Fix a (prime) modulus $M$ (preferably between $10^9$ and $2\cdot 10^9$), and a base $B$ (preferably a generator modulo $M$) and define the polynomial hash of the string $S = S_0S_1\cdots S_{n-1}$ as the following: $$\text{hash}(S) = \left(\sum_{i=0}^{n-1} H[S_i]B^i\right) \bmod M$$ where $H[c]$ is some fixed value from $0$ to $M-1$ assigned to $c$.
If $M$ and $B$ are chosen well, two strings $S$ and $T$ are equal if and only if $\text{hash}(S) = \text{hash}(T)$ with high probability, and $S$ is a palindrome iff $\text{hash}(S) = \text{hash}(S^R)$ with high probability ($S^R$ is the reversal of $S$).
If we are given two strings $S$, $T$ and their hashes, then the hash of $ST$ (their concatenation) can easily be computed in $O(1)$ time (assuming we have precomputed the powers of $B$).
Preprocess $S$ so that we can compute the polynomial hash of any substring and reversal of any substring in $O(1)$ time.
Next, to answer the query $(i,j,k,l)$, first check if $[k,l]$ intersects with $[i,j]$. If not, we can simply compute the hash of $S[k,l]$ and its reverse. Otherwise, split $[k,l]$ into three parts, where the middle part is contained completely in $[i,j]$. The hashes of the three parts (and their reverses) can be computed separately (with the middle one requiring special care), and can be concatenated in $O(1)$ time and compared. If the hash of the string and its reverse match, then the answer is "Yes", otherwise it is "No".
When faced with a problem, there are a couple of helpful general tips and strategies that might help you solve it:
There are times when these tips do not apply, and those cases usually require a lot more thinking and thus are usually more interesting. But let's try to apply these strategies in the problem at hand.
How can we simplify the problem? Well, of course we can reduce the bounds of $|S|$ and $Q$ to, say, $\le 10^3$, but in that case the answer is easily brute-forceable, so it doesn't get us closer to a fast solution.
Well, we can simplify the problem by removing the "reversal" operation for each query, i.e. each query consists of two integers $(k,l)$, and you need to tell whether the substring from the $k$th position to the $l$th position is a palindrome. (You can view this simplified problem as a special case of the original problem with $i = j = 1$, for example) Now this simplification is more interesting :)
In this case, one can apply standard palindrome algorithms like Manacher's algorithm to determine the longest palindrome centered at each position. This takes $O(|S|)$ preprocessing and $O(1)$ query time. However, this solution doesn't adapt well once we add in the reversal operations, so let's try to find another solution.
At this point, we try to find what else can be done to check for palindromes. Well, what else are standard algorithms for this task? Hashing, of course! In fact, in many occasions one might prefer a hashing algorithm instead of Manacher's algorithm because it's more flexible, and easier to implement (whereas Manacher's algorithm can be tricky to implement, and is not as flexible).
A string is palindromic if and only if it is equal to its reversal. However, the reversal of any substring of a string $U$ is a specific substring of the reversal of $U$. In more detail, if we denote the reversal of a string $S$ by $S^R$, then we're saying that if $U[i..j]$ is a substring, then $U[i..j]^R = U^R[N+1-j..N+1-i]$, where $N$ is the length of $U$. Therefore, we have reduced a query into a case of comparing whether substrings of two strings are equal. But substring comparisons can be done quickly using polynomial hashing!
A hash is simply a function that maps an object of an arbitrary size (such as a string) into an value of fixed size (such as a bounded integer).
There will inevitably be pairs of objects that will be mapped to the same value (in fact, infinitely many of them). We call a situation where two different objects are mapped to the same hash value a collision. Collisions are inevitable, however we desire hash functions such that it is "random" enough so that for any string we will hash, it will be assigned a hash value with equal "probability" among all possible hash values, and that it is not particularly easy to generate different strings with the same hash value.
One application of hash values is in comparing strings: If our hash function is good enough, then two different strings have hashes with high "probability". Let's be a bit more specific. Suppose that our hash function maps strings to integers from $0$ to $M-1$. Suppose that we have two different strings $(S,T)$. If we assume that the hash function is "random" enough, then the "probability" that $S$ and $T$ have different hashes is $\approx 1 - 1/M$, which is pretty close to $1$ assuming $M$ is large. If we want to compare $K$ pairs of different strings $(S_1,T_1), \ldots (S_K,T_K)$, then the probability that every pair have different hashes is $\approx (1 - 1/M)^K$.
In our case, we will need to compare $K \approx 10^5$ pairs of strings, so if we choose $M$ to be around $10^9$, then the probability that no collision will occur is approximately $(1 - 1/10^9)^{10^5} \approx .9999$. Therefore, our chances of succeeding are pretty high!
One common hash function is the polynomial hash. To compute polynomial hashes, we first fix two integers $M$ and $B$. Also, for every character $c$ alphabet, we assign a fixed value $H[c]$ (for example, the ASCII value of $c$). Then the polynomial hash of the string $S = S_0S_1\cdots S_{n-1}$ is the following: $$\text{hash}(S) = \left(\sum_{i=0}^{n-1} H[S_i]B^i\right) \bmod M$$ Clearly the result is a number in $[0,M-1)$, but to minimize potential easy "collisions", we ensure that $M$ is prime, and that the order of $B$ modulo $M$ is reasonably large.
Why did we choose the polynomial hash? Because it has other advantages that will be useful in our case:
This is great, because this gives us an $O(1)$-time algorithm to answer our query: preprocess the string $S$ and its reversal $S^R$ as above, and simply check if the hashes of $S[k..l]$ and $S[k..l]^R = S^R[N+1-l..N+1-k]$ are equal! The overall algorithm runs in $O(|S| + Q)$.
Now, we go back to the original problem, where each query has a reversal operation. Let's try to answer the query $(i,j,k,l)$, where the substring $S[i..j]$ is reversed temporarily.
Our goal is to be able to compute hashes of substrings assuming that $S[i..j]$ has been reversed. Let's handle the simple cases first:
Therefore, we only have two remaining cases to handle:
But in these cases, we can split the string $S[k..l]$ into at most three parts, where each part is either completely contained in $S[i..j]$, or completely outside. We have just described above how compute the hashes of each of the parts quickly, and we can compute the hash of the concatenation of two strings quickly (using the identity in the previous part). Therefore, we now have an algorithm to compute the hash of any substring $S[k..l]$ assuming some substring $S[i..j]$ is reversed temporarily! Since we only compute hashes of a fixed, bounded number of parts, this operation takes $O(1)$.
Since we can now compute hashes of substrings even when some substring is temporarily reversed, we can now answer queries $(i,j,k,l)$ in $O(1)$ time!
Here are some other links about polynomial hashing that might be useful to you:
$O(|S| + Q)$
While going through the editorial of the MBOARD problem I came up across the idea of solving the ORDERSET problem using the BIT data structure. I had solved the ORDERSET problem by augmenting a balanced binary tree. But I could come up with no idea of how to solve the problem with a BIT. So if people can put together their ideas on this, I will be really thankful. Thanks.
I don't know why it is giving wrong answer. i tried it with many test cases but i still can't point out the issue. Problem iink and my solution link are:
https://www.codechef.com/problems/PALIN
https://www.codechef.com/viewsolution/14249426
Thanks in advance.
Problem Link
Prerequisites
Binary Search
Quick Overview
Given an array and two ranges you need to find whether the subarray lying in these two ranges have mismatch of less than 1 or not when elements are compared correspondingly in a sorted order
Solution
For 10 Points
It's quite easy you can just copy the two subarrays in the new array and sort it in O(N log N) and check the corresponding values for mismatch.if mismatch is more than 1 output NO else YES.
My Solution using this click here
For 100 Points
I used a simple approach in O(n) with some optimization.
What I did was made a frequency array for all values.Since A[i]<=100000 it's feasible.
When u will create this frequency array we can easily maintain that values inserted in the vector are in sorted order only.
Now you can simply iterate over all values of given array from a to b and check the frequency of that value in two range [a b] and [c d] using Binary search.Two cases arise then:
IF diff in freq==1
we store the index of that value which is more in either range and increment our counter.
IF diff in freq>1
it means that 2 or more elements are different & hence no need for further search we can break the operation and print NO.
Now if till end diff in freq ==0
Answer is obvious YES
but if diff in freq ==1
You need to check that if there is some element which lies between these two different elements or correspondingly you can found the rank of those different element in both arrays.
If rank is same:
They will be at same position & hence output YES
else
They will lie at different position & hence output NO
Optimization
I did was avoid checking same values by maintaining a bitset. It compensates for the time taken in the binary search to count frequency.
I changed a,b,c,d for overlapping ranges to avoid searching for the same element.
Here is the solution to my code implemented that way.
Author:Maksym Bevza
Tester:Arjun Arul
Editorialist:Misha Chorniy
Simple
none
You are given tree consisting $N$ nodes. Each node $i$ has value $P_{i}$ assigned to it. All values $P_{i}$ are distinct. For each node $j$ find maximal value of node in the graph if to remove nodes adjacent to $j$ and $j$.
$N$ is less or equal than 10000. For each node will mark all nodes which are adjacent to it as dead(not usable), will find maximum value between non-marked nodes.
for i= 1..N
//Step 1
for j=1..N
alive[j] = 1; //initialize all marks as ones
//Step 2
alive[i] = 0; //mark itself as dead
for v is adjacent to i //mark all adjacent nodes
alive[v] = 0; //mark neighbours as dead
ans[i] = 0;
//Step 3
for j=1..N
if alive[j]==1 //if node j is alive
ans[i]= max(ans[i],p[j]); //find maximum value
How long it works? Obviously, the complexity of first and third step is $O(N)$, how to find the complexity of the second step? Denote $D(v)$ - degree of node $v$, for vertex $i$ complexity of step 2 is equal to $D(i)$, over all iterations complexity of second step is $D(1)$+$D(2)$+..+$D(N)$, what is $2*(N-1)$ for trees, we see that each edge using exactly two times. Total complexity of this algorithm is $O(N*N+2*(N-2)+N*N)$ = $O(N^2)$
First and third steps are slowest in the code above, how to optimize it? We can rewrite that code a bit.
for i=1..N
alive[i]=1;
for i=1..N
alive[i]=0;
for v is adjacent to i
alive[v] = 0;
ans[i]=0;
for j=1..N
if alive[j] == 1 //if node j is non-marked
ans[i] = max(ans[i],p[j]); //update answer
alive[i]=1;
for v is adjacent to i
alive[v] = 1;
Now total complexity is $O(N+2*(N-2)+N*N+2*(N-2))$ = $O(N^2)$, still $O(N^2)$, we can make some observations, basically we have set, where the following operations can be performed:
Let's use some data structure, namely in our case, the data structure which can add/erase elements, and find the maximal value in the set of these elements, but does this thing in time less than $O(N)$.
for i=1..N
add(P[i]);
for i=1..N
erase(P[i]);
for v is adjacent to i
erase(P[v]);
ans[i] = getMaximalValue();
add(P[i]);
for v is adjacent to i
add(P[v]);
What is the best data structure for these things, in most of the modern programming languages exists built-in data structures for such things, in C++ you can use set, Java has Set, Python has similar data structures. If your language doesn't have built-in data structures, you can read about heaps (http://pages.cs.wisc.edu/~vernon/cs367/notes/11.PRIORITY-Q.html) and realize it.
Let's write code with the map in C++, the similar code can be written in Java with Map or in Python with the dictionary.
set < int > S;
for i=1..N // Step 0
S.insert(P[i]); //Initialize set
//Adding element P[i] in the set
for i=1..N
//Step 1
S.erase(P[i]); //Erase value of node i from set
for v is adjacent to i //Iterate over neighbours of node i
S.erase(P[v]) //Erase values of neighbours of i
//Step 2
if !S.empty()
ans[i] = *S.rbegin(); //Value of greatest element
//Step 3, rollback of the step 1
S.insert(P[i]); //Insert value of node i from set
for v is adjacent to i //Iterate over neighbours of node i
S.insert(P[v]) //Insert values of neighbours of i
Complexity of adding/erasing of number in such data structures is $O(log N)$, summary complexity of the first steps is $O(N log N)$, the same is for third steps, Total complexity is $O(N log N + N log N + N log N + N log N)$ = $O(N log N)$
The overall time complexity of this approach is $O(N log N)$.
Setter's solution can be found here
Tester's solution can be found here
Please feel free to post comments if anything is not clear to you.
Author:admin2
Testers:Hasan Jaddouh
Editorialist:Pawel Kacprzak
Cakewalk
None
There are $n$ people and $2 \cdot m$ of them already formed pairs. The task is to answer the question if all the remaining unpaired yet $n-2 \cdot m$ people can be connected into pairs.
In the input, exacts pairings for $2 \cdot m$ people are also given, but this is completely irrelevant to solving the problem. Since a pair consists of $2$ different people and one person wants to be a part of exactly one pair, the all remaining $n-2 \cdot m$ people can be connected into pairs if and only if $n-2 \cdot m$ is even. You can also notice that for integer $m$, $n - 2 \cdot m$ is even if and only if $n$ is even, so we can as well check the parity of $n$. It follows that the time complexity for answering a single test case is $O(1)$.
Setter's solution can be found here.
Tester's solution can be found here.
Editorialist’s solution can be found here.
why I should do CP? how it will help me in future in term of job in IT sector? I have just completed my 2nd year and will enter in 3rd year in august 2017. IS i am toolateforCP ? I know only basic data structure (stack,queue) etc And basic programming skill.
I tried solving D-Query http://www.spoj.com/problems/DQUERY/ using Mo's algorithm, but my code keeps giving Segmentation Fault, have been trying for the past hour and still can't debug it. Would appreciate it if someone can help. Thanks. Here is my code.http://ideone.com/o9qLUW
hi all...as a newbie i wanted to all about ACM-ICPC contest....how to prepare for it and also tips from u...how u cracked it !!
Hey guys, Can you explain your approach to solve PRMQ from june 17 long? I am aware BIT is being used in most solutions. I am not able to decipher how the thing works. Thanks!
Hi, I just want to know how I can get a string from stdin which contains whitespaces? I tried fgets and scanf("%[^\n]",str) but it's still not working
In the recently concluded Long challenge, in the problem "CLONEME", I wrote an optimal brute force solution. The solution is as follows :
$S_1 - S_2 = a - b$ and ${S_1}^2 - {S_2}^2 = a^2 - b^2$.
Then $a + b = \frac{{S_1}^2 - {S_2}^2}{S_1 - S_2}$ i.e. ${S_1}^2 - {S_2}^2$ should be divisble by $S_1 - S_2$.
Also, if $S_1 == S_2$, this means atleast 2 elements differ as, there not permutation as assured by the prefix sums checked above.
Now, using difference in sum of cubes in the 2 subarrays, I confirm again if the 2 elements I found are valid out. i.e if the difference of the sum of cubes of 2 subarrays is exactly equal to the difference of the cube of the 2 numbers found.
If all the above methods fails, I simply do a brute force algorithm, i.e. construct the 2 subarrays, sort them and then check if they mismatch at one position only.
I had tried to construct test cases such that my solution TLE, but was unsuccessful. Can someone here would like to challenge my solution for the problem ?
Remember, that almost all the queries should be different as I should cache the previous queries answer which is generally used and such test cases are avoided by making problem. (i.e. if you find a particluar query for which my solution will execute the brute force solution, then do not give the same query again and again in the test case).
Happy coding :)
Author:Praveen Dhinwa
Tester:Hasan Jaddouh
Editorialist:Sidhant Bansal
DIFFICULTY -
Easy
PREREQUISITES -
Loops
PROBLEM -
An array of $N$ animals, consisting only of snakes and mongooses in a particular order is given to you. Given that each mongoose can eat at most one snake immediately adjacent to it, determine whose frequency is greater given that the mongoose eat optimally so as to minimise the frequency of the snakes.
QUICK EXPLANATION -
The question is of ad - hoc and greedy type. The question states It can be easily solved if each mongoose uses the greedy strategy of first checking if its immediate left neighbour and if not possible to eat it then check its right neighbour.
EXPLANATION -
Iterate over all the mongoose from left to right and for each mongoose check if its immediate left neighbour can be eaten, if yes, then increment the answer and move to the next mongoose. Otherwise, check if its immediate right neighbour can be eaten, if yes, then increment the answer and move on. By checking a neighbour we mean, we need to check that the particular position is occupied by a snake which is NOT eaten already.
The pseudocode will be -
bool eaten[N]
int T
input T
FOR i = 1 to T:
string S
input S
int snakes = 0, mongooses = 0, answer = 0
FOR j = 0 to S.length() - 1:
eaten[j] = 0
FOR j = 0 to S.length() - 1:
if(S[j] == 'm'):
mongooses++
if(eat(j - 1)):
answer++
else if(eat(j + 1)):
answer++
else:
snakes++
snakes -= answer
if(snakes > mongooses):
print "snakes"
else if(mongooses > snakes):
print "mongooses"
else:
print "tie"
bool eat(int x):
if(x < 0 or x >= S.length()):
return false
if(S[x] == 's' and eaten[x] == 0):
eaten[x] = 1
return true
return false
Time Complexity -
Time complexity per test case is $O(N)$, therefore the total time complexity is $O(N * T)$
What is the approach to solve CLONEME for 30 and 100 pts?