Quantcast
Channel: CodeChef Discuss - latest questions
Viewing all 40121 articles
Browse latest View live

SUBGRAPH - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Kanstantsin Sokal
Tester:Jingbo Shang
Editorialist:Lalit Kundu

DIFFICULTY:

Medium-Hard

PREREQUISITES:

DP on trees, graphs

PROBLEM:

You are given an undirected graph $G$ of $N$ nodes and $M$ edges. It's guaranteed that no multiple edges or self-loops appear in the graph as well as that the graph is connected. There's one more restriction on the graph: any node of $G$ belongs to at most one simple cycle in $G$.

Your task is to count the subsets of nodes in $G$, such that the nodes in the subset are connected (you can reach any node of the subset from any other node of the subset only by moving to adjacent nodes that belong to the subset) and contain no more than $K$ nodes.

QUICK EXPLANATION:

================
Cycle main node
Each cycle has the main node: it's a node, which, if we make the graph $G$ rooted, will be connected to some node of the cycle, which is an ancestor cycle for our cycle.

For each cycle main node $v$, we define $\text{f}(v, k)$ as the number of subgraphs rooted at node $v$ and having $k$ nodes in it. This $k$ also includes non-main nodes and not just the nodes in compressed tree. For each non-main node, we define we define $\text{g}(v, k)$ as the number of subgraphs rooted at node $v$ and having $k$ nodes in it and these subgraphs don't have any of the nodes of $\text{cycle}[v]$. That means, it only depends on the main nodes that come out of node $v$. So, we can recursively define $\text{g}(v, k)$ based on values of $f$.

Now, for recursively calculating values of $f$, we consider each subsegment of cycle of main node $v$ and, then for all subsegments, for all nodes in current subsegment calculate number of subgraphs using values of $g$. If such a subsegment has node $v$ in it, then we add the value calculated to $f(v)$.

Add to answer the values calculated by considering each subsegment.

EXPLANATION:

================
DP solution to realise in this problem is a little difficult. I am going to explain author's solution here.
First lets discuss an easier problem which says: Given a tree calculate number of subtree's with exactly $K$ nodes. Here we need to use DP on tree. For each node $v$, we define $\text{dp}(v, k)$ as number of subtrees with $k$ nodes and $v$ as root. Now, we can define recurrence relation for this. Let's say for node $v$, there are direct children nodes $u_1, u_2, ... u_n$. Now, to form a subtree with $k+1$ nodes rooted at $v$, lets say direct children nodes contribute $a_1, a_2, ..., a_n$ nodes, where $a_1 + a_2 + ... + a_n = k$, in this case we add to $\text{dp}(v, k)$ the value $\text{dp}(u_1, a_1)*\text{dp}(u_2, a_2)*...*\text{dp}(u_n, a_n)$. We should do this for all possible $a_1, a_2, ..., a_n$.

To do this, we create one more DP here $\text{dp1}(i, j)$ as number of ways to choose a total of $j$ nodes from subtrees defined by $u_1, u_2, ..., u_i$. The recurrence can be defined as $\text{dp1}(i, j) = \sum_{k=0}^{K} \text{dp1}(i-1,j-k)*\text{dp}(i, k)$. So, in terms of pseudo code we can write something like:

dp[N][K+1]

void rec(int cur_node){

     dp[cur_node][1]=1

     for(all v such that v is children of cur_node)
      rec(v)

      dp_buffer[K] = {0}
      for i=0 to K:
           for j=0 to K-i:
                dp_buffer[i + j] += dp[i]*dp[v][j]

      dp[cur_node] = dp_buffer
}

Hence, our problem is solved. We do something similar in our given graph, but since cycles are involved, we need to do something improvised. You should here notice that if we compress all cycles to form a single node, then our graph is a tree, say $T$. You should also note that non-bridge edges in $G$ are the edges which will be the edges of tree $T$.

First, a definitions I'll be using:
Cycle main node
Each cycle has the main node: it's a node, which, if we make the graph $G$ rooted, will be connected to some node of the cycle, which is an ancestor cycle for our cycle. Or, in other words after rooting $G$, if I apply DFS then main node of a cycle will be visited earliest. For example, in following image nodes $1$, $2$, $5$, and $9$ are main nodes, if $G$ is rooted at node $1$.

All other nodes can be called as non-main nodes.

Now, first we parse cycles in graph $G$, which means compressing each cycle to a cycle main node and for each cycle store the vertices in it. Let's denote by $\text{cycle}[v]$ as the cycle id of node $v$. Now, we are going to compute DP on this compressed tree and at the same time also maintain data about the cycles in it.

So, we define $\text{f}(v, k)$ for all main nodes $v$, the number of subgraphs rooted at node $v$ and having $k$ nodes in it. This $k$ also includes non-main nodes and not just the nodes in compressed tree. Now, we cannot just calculate function $f$ recursively using its own definition, we need to also include the fact that main node $v$ is not just a single node but a cycle.

So, for non-main nodes $v$, we define $\text{g}(v, k)$ as the number of subgraphs rooted at node $v$ and having $k$ nodes in it and these subgraphs don't have any of the nodes of $\text{cycle}[v]$. That means, it only depends on the main nodes that come out of node $v$. So, we can recursively define $\text{g}(v, k)$ based on values of $f$. This DP is quite similar to what we discussed in the easier problem. So, in terms of pseudo code we can write:

g[N][K]

void rec(int cur_node, int prev){

     g[cur_node][1]=1

     for(all edges e incident with cur_node):
      //we just want to consider children of cur_node
      //which are main nodes
      if e is the edge (cur_node, prev) or if e is not a bridge:
           continue

      u = neighbor of v via edge e
      rec(u, v)
      dp_buffer[K] = {0}
      for i=0 to K:
           for j=0 to K-i:
                dp_buffer[i + j] += g[i]*f[u][j]

      g[cur_node]=dp_buffer

}

Now, that we have calculated $g$ array at current main node, lets see how we will calculate $f$ for the current main node again, based on recursive definition. Now, you should notice how we can make subgraphs at a main node. For example, in the following image, the six different color curves denote which non-main nodes are we going to include in our subgraph at node $v$.

So, the different subgraphs we have made are:

  • color pink: $v$, $S(u_3)$, $S(u_1)$, where $S(x)$ denotes the subtree of node $x$.
  • color green: $v$, $S(u_1)$, $S(u_2)$, $S(u_3)$
  • color red: $v$, $S(u_1)$
  • color blue: $v$, $S(u_1)$, $S(u_2)$
  • color yellow: $v$, $S(u_2)$, $S(u_3)$
  • color cyan: $v$, $S(u_3)$

You should notice that we are considering all subsegments in cycle of node $v$(because we need subgraph connected) and then for each subsegment we can use $g$ to calculate number of subgraphs which include subtrees of all these nodes. Also, if for a subsegment main node lies in that segment we can use it to calculate $f$ for main node $v$.

Lets formalise things a bit. Let's say you are considering subsegment of nodes formed by nodes $u_1, u_2, ..., u_n$. We already have calculated $g(u_i, k)$ for all $i$ and $k$. Now, at this step we'll also be adding the subgraphs caused by this subsegment to our final answer. We define $h(k)$ as number of such subgraphs with $k$ nodes. So, the subgraph we are considering is formed by $S(u_1), S(u_2), ..., S(u_n)$. So, for calculating $h(k+n)$ we assume that we have choosen $a_1, a_2, ..., a_n$ from each of these subtrees, where $a_1 + a_2 + ... + a_n = k$, so to $h(k+n)$, we add $g(u_1, a_1) * g(u_2, a_2) * ... * g(u_n, a_n)$. Now, we should do this for all possible sets of $a_i$.

Again, for calculating this we can do very similar to what we did in the easier problem in beginning.

h = g(u_1)
for i = 2 to n:
     dp_buffer[K] = {0}

     for j = 1 to K:
      for k = 1 to K-i:
           dp_buffer[j + k] += h[j]*g(u[i], k)

     h = dp_buffer

     //at this step dp_buffer stores h(k) for the set of nodes
     //u_1, u_2, u_3, ... u_i
     //so to our final answer we should add this whole array h
     for j = 1 to K:
      ans[j] += h[j]

     //if subsegment u_1 to u_i contains main-node v
     //then to f(v, i) we should add h(i) for all i
     if subsegment u_1 to u_i contains main-node v:
      for j = 1 to K:
           f(v, j) += h[j]

We do the above process for all possible $u_1$ i.e. all possible subsegment starts. You need to take care of a few things:

  • Be sure to count the whole cycles as a subsegment only once(it can be done to iterating through the whole cycle only from the main node of the cycle)
  • Be sure to consider $g(u_i, k)$ for $k \ge 1$, i.e. node $u_i$ is present always(otherwise chain will not be connected).

So, in this way we we'll have iterated over all possible subsegments which can possibly contribute to the answer. Now, we just have to take sum of $\text{ans}[i]$, for all $i \le K$.

COMPLEXITY

================
Let's say $l$ is size of cycles and $n$ is number of cycles.
Then for each subsegment of cycle i.e. a total of $l^2$ subsegments, we do a computation of $K^2$. Also, for calculating $g$ for each non-main node, we do a computation of $K^2$, where non-main nodes could be atmost $N$.
So, our complexity is $O(n * (l^2 * K^2) + N * K^2)$ which we can say is less than $O(n * (l * L * K^2) + N * K^2)$ $=$ $O((N * L * K^2) + N * K^2)$ = $O(N * L * K^2)$.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester


Suggested Changes

$
0
0

With the increasing amount of users being participating in Codechef contests and the problems the site is going through, here I some changes which I would like to suggest-

1)First of all, There has been a lot on discussion these days about the uploading of video tutorials for the problems. I think it is not a feasible step. We can't even argue about the credibility of such video tutorials. The editorialists for the problems are much more experienced and can tell the solution more beautifully. I very well understand the problem many of you are facing while understanding the editorials, (I also face the same problem), so I have found some other feasible solution for it. Instead of asking just one person to write the Editorials, Codechef can ask 5 different persons to write the Editorials for the problem and then select the best 3 of them and post them. Also to make the tutorial more interesting, solution and approach should be explained subtask wise, as it is seen in the Editorial for Lunch-Time problems. This is help new users to atleast solve the problem partially and later when they learn the required data structures and algorithms, they solve it fully. Also, some link to 1-2 previous questions based on similar concept can be added in the Editorials. I think it is much more feasible than uploading video tutorials on youtube or on this site.

2)Also, more short contests, example 2 Cook-offs should be organised as they are more useful. Most of the contests like ACM-ICPC etc are short contest. Long contest rarely happen anywhere, that to with maximum stretch of 2 days. Organising more short contests, as Codeforces organises 5 short contests per month, topcoder also organises many more short contests as well, will help not increase the popularity of Codechef more, but also help users prepare much more for real-world contests. These 2 Cook-offs could be broken up into Division 1 and Division 2 as well if possible. This will help motivate the new users to atleast gain confidence by solving more problems in easier contest and try harder for tougher one.

3)The total time for long challenge should be reduced from 10 days to 7 days. Actually, many of the users solve most of the questions on one to two days only and rarely you see them submitting solutions to other problems later. Reducing the time to 7 days will give Codechef more time to organise the other Cook- off as well.

4)The previous (just about 1 year old) Cook-off's should be made as virtual contests, which means users have to solve the problems in the same format with the time limit, but this will not affect the ratings. They can have a look at their performance by looking up the rankings table for that Cook-off. This idea has already been implemented on Codeforces and some other sites. This encourages the users to get more exposure to real time contests and develop speed and accuracy for solving problems.

5)Also, there has been increased discussions about solving problems related to particular topic. I think this is not useful. What Codechef can do is classify the 5 easiest problems on each topic and put them in Beginner section and leave the rest of the problems in Easy, medium and hard level as it is. This will be more useful. If we solve problems topic wise, it will not be much useful. To get started about 5 problems with bit increasing difficulty on that topic is enough. Then we should solve questions randomly. If we solve questions topic wise, we may become expert in that topic and solve almost all questions related to that topic. But in the contest, the first real challenge is to identify the problem and the method to solve it. many a times we are are expert in the method problem asks for but we can not able to identify it. We later regret for our silly mistake or whatever. Only when we solve questions randomly, we open up or mind more and start identifying the problems more quickly.

I think the above steps will make problem solving more interesting and beneficial. This will also help to reduce the fear of Competitive coding among the new users.

Please vote this question so that the message reaches the Codechef admin as soon as possible and they can take the required steps.

CHANGES IN CODECHEF SITE

$
0
0

Finally, the Old type of Codechef site is back. The colour on the question show that we have either solved the question fully, partially or whether it is wrong. The best thing is that the Announcements have been moved to the top of Contest page after the questions which makes it easy for us to see the changes. Also, the School label has been changed to Beginners which is a good move. Hope the contest ranking also appear soon on the contest page as well. Also, the new plagiarism testing is also on the way as told by the admin himself.

One more important notice for everyone. Almost most of us are aware that coding on ideone is not safe especially during the contests as our code can be easily seen (or hacked) by others and copied. This can lead to plagiarism and decrease in our rating points. I have been using Codechef IDE for about 3 months. It was a good experience. But now, it is even better. You can select the contest and the required problem. So, you can see the question and code on the same page. This think has been earlier used on Hackerrank and other sites. Happy that Codechef has also started it. For those, who have not installed any compiler and practice on ideone, I suggest them to use the Codechef IDE as well. Hope, you will also like it. You can also save your coding template in various languages on the IDE. So, when you login or start coding on the IDE, the template is available and use can easily just code out your logic. Also, it user friendly and has various options for changing the settings, downloading your code etc. The best is that your code is safe. No other user/person can view it until you submit the solution for your problem and the solutions are made public. GREAT WORK BY CODECHEF....

Thanks Codechef again for rolling back most of the changes. Hope that it stays forever..

Also, please post your comments regarding the new changes in the site. The best thing is Codechef is there to here you and serve you the best..

Happy Coding :)

TWOSTR - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Tasnim Imran Sunny
Tester:Istvan Nagy
Editorialist:Lalit Kundu

DIFFICULTY:

Cakewalk

PREREQUISITES:

basic programming, strings

PROBLEM:

Chef wants to implement wildcard pattern matching supporting only the wildcard '?'. The wildcard character '?' can be substituted by any single lower case English letter for matching. He has two strings $X$ and $Y$ of equal length, made up of lower case letters and the character '?'. He wants to know whether the strings $X$ and $Y$ can be matched or not.

EXPLANATION:

================
We can reduce problem of matching two strings $X$ and $Y$ to matching individual characters for each index $0 \le i < N$. If all characters can be matched, then we can say that both strings can also be matched.

MATCHING A CHARACTER

We need to check if two characters $a$ and $b$ can be matched or not. If either of them is '?', then we can always match them by filling it with the required value. If both are '?', still we can give any same value to both of them.

If both are not '?', then we just need to check if the current values are same or not.

For implementation, see setter's commented code.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester

XORNUBER - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Tasnim Imran Sunny
Tester:Istvan Nagy
Editorialist:Lalit Kundu

DIFFICULTY:

Simple

PREREQUISITES:

bitwise operators, basic maths

PROBLEM:

Given an integer $N$, Chef wants to find the smallest positive integer $M$ such that the bitwise XOR of $M$ and $M+1$ is $N$. If no such $M$ exists output $-1$.

EXPLANATION:

================

First thing you should while trying to solve this problem is to see how XOR of two consecutive numbers behave. As we know XOR of two same bits is $0$ while XOR of two different bits is $1$.

Now, let's say we have a number $M$ and we are going to add $1$ to it.

If last(least significant) bit of $M$ is $0$(i.e. $M$ is divisible by $2$), then $M+1$ will be exactly same as $M$ except the last bit which will be set. Formally, if $M = b_1, b_2, ... , b_n$, and $b_n == 0$, then $M+1$ is $M+1 = b_1, b_2, ... , \bar{b_n}$(we denote not of a bit $a$ by $\bar{a}$). So, $M$ XOR $M+1$ in this case is going to be $1$, because all other bits are same.

What if least significant of $M$ is set? In that case, we have to keep a carry which keeps moving towards significant bits. Now, this carry at any position is at most $1$. So, the first position(while moving from least to most significant position) at which a $0$ is present in $M$, our computation will end.

So, we can say that to add $1$ to a number $M$ we start from least significant position and keep flipping set bits until we get an unset bit, which we have to set and we are done. Formally, if $M = b_1, b_2, ... , b_n$, we find largest $i \le n$ such that $b_i ==0$ and $b_j == 1 \forall j>i$. We can say that $M+1 = b_1, b_2, ..., \bar{b_i}, \bar{b_{i+1}}, \bar{b_{i+2}}, ..., \bar{b_{n}}$.

For example, if number is $10111$, for adding $1$ to it, first we start from right to left and keep flipping bits until we get a not set bit, at the step we set that not set bit, so it will give $11000$. Similarly, adding $1$ to $10001111$ will give $10010000$.

Now, notice that all less significant bits beginning from the least significant unset bit(i.e. index $i$) have been flipped after adding $1$ and all other bits remain same. So, XOR of $M$ and $M+1$ is always of form $2^K-1$, where total number of set bits is $n-i+1$.

Now, for a given $N$, if its not of form $2^K-1$, we can directly say its not possible to find a positive integer $M$ such that the bitwise XOR of $M$ and $M+1$ is $N$.

Or else, if there are $k$ set bits in $N$, then we need to form smallest positive number. You need to observe that for $k$ bits to be set, the index $i$ should be $n-k+1$ because beginning from index $i$ all bits are set if we take XOR. Now, it is very easy to infer that if there are $k$ set bits in $N$, then XOR of $2^{k-1}-1$ and $2^{k-1}$ will give us $N$. For example, $N=7$ has $3$ set bits i.e. $N=111$(in binary). Now, taking XOR of $11$ with $100$ will give us $N$.

Tricky Case:
$N=1$ is a tricky case here. We remember that for even $M$, $M$ XOR $(M+1)$ is $1$. So, smallest such $M$ is $2$.

For checking if a number is of form $2^K-1$, you can keep checking bits by repeated division or various bit tricks can also be employed.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester

SEQLCS - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Tasnim Imran Sunny
Tester:Istvan Nagy
Editorialist:Lalit Kundu

DIFFICULTY:

Medium

PREREQUISITES:

dynamic programming, bitmasking

PROBLEM:

Given a sequence $A$ of $N$ integers where each integer lies between $1$ and $K$ and an integer $L$, count number of different sequences $B$ of length $N$ such that longest common subsequence(LCS) of $A$ and $B$ is $L$.
$N, K, L \le 16$.

QUICK EXPLANATION:

======================
We define $\textrm{DP}(i, \textrm{arr})$ as number of ways to add $i$ more integers to array $B$ such that $\textrm{arr}[i]$ denotes LCS of $i^{th}$ prefix of $A$ with current elements in $B$).

$\textrm{DP}(i, \textrm{arr}) = \sum_{j = 1}^{K} \textrm{DP}(i - 1, \textrm{next}(\textrm{arr}, j))$, where $\textrm{next}(\textrm{arr}, j)$ returns the new updated $\textrm{arr}$ after adding value $j$ at the end of array $B$.

We can represent this array $\textrm{arr}$ by a bitmask of $N$ values, where $i^{th}$ bit is set if $arr_{i} > arr_{i-1}$.

Function $\textrm{next(mask, i)}$ can be precalculated for each pair of $\textrm{mask}$ and value $i$.

EXPLANATION:

================

While constructing a dynamic programming solution, it is always a good idea to iterate over something (usually the state of dp). Let us say that we are constructing array $B$ from left to right, let us say that we know LCS of $A$ and currently constructed part of $B$(let us denote it by $l$). So, now we need to ask ourself about what information we should maintain in the state so that when we put the next elementof array $B$ as $x$ , how can we find new value of $l$ efficiently.

Now, by using only previous $l$, can we find new value of $l$? Think about it, it is not possible.

So, if we have two sequences $a_1, a_2, ..., a_p$ and $b_1, b_2, ..., b_q$ and we progressively keep adding values at the end of sequence $b$, how can we can re-calculate $\textrm{LCS}(a, b)$ quickly? For this, we need to have a proper understanding of how LCS is calculated.

We define $\textrm{LCSdp}(i, j)$ as the LCS of $a_1, a_2, ..., a_i$ and $b_1, b_2, ..., a_j$. Now,
$\textrm{if}(a_i == b_j)\hspace{1mm} \textrm{then}\hspace{1mm} \textrm{LCSdp}(i, j) = \textrm{LCSdp}(i - 1, j - 1) + 1$
$\textrm{else} \hspace{1mm} \textrm{LCSdp}(i, j) = \textrm{max}(\textrm{LCSdp}(i, j - 1), \textrm{LCSdp}(i - 1, j))$

Now assume, we have sequences $a_1, a_2, ..., a_p$ and $b_1, b_2, ..., a_q$. We add one more value $a_{q+1}$. How do we re-calculate LCS? We need to maintain some information with us, or else, we'll have to calculate the whole $\textrm{LCSdp}$ matrix again. If we have with us
$\textrm{LCSdp}(1, q), \textrm{LCSdp}(2, q), ..., \textrm{LCSdp}(p, q)$
which is nothing but an array of LCS of each prefix of $a$ with whole array $b$, then we can easily find values
$\textrm{LCSdp}(1, q+1), \textrm{LCSdp}(2, q+1), ..., \textrm{LCSdp}(p, q+1)$
which denotes LCS of each prefix of $a$ with updated $b$. How? Think before you read ahead.

If at any position $j$, $a_j == b_{q+1}$, then $\textrm{LCSdp}(j, q+1) = \textrm{LCSdp}(j - 1, q) + 1$
or else, $\textrm{LCSdp}(j, q+1) = \textrm{max}(\textrm{LCSdp}(j - 1, q + 1), \textrm{LCSdp}(j, q))$.
Note that if we calculate new array from left to right, we'll have all values available on right hand side.

Now, how does all this help us? We are going to formalise our DP in a way such that at each step, we are going to progressively add more elements to array $B$. We can directly use the $\textrm{LCSdp}$ array as one of the state parameters of DP.

So, states of our DP are $\textrm{number of elements to be added}$ and $\textrm{current LCSdp array}$.
We define $\textrm{DP}(i, \textrm{arr})$ as number of ways to add $i$ more integers where $\textrm{arr}$ contains the current $\textrm{LCSdp}$ array($\textrm{LCSdp}[i]$ denotes LCS of $i^{th}$ prefix of $A$ with current elements in $B$). So, how can we define the recurrence of our DP?

At each step, we assume that we add value $j$ at the end of array $B$. So we traverse over $j$. $\textrm{DP}(i, \textrm{arr}) = \sum_{j = 1}^{K} \textrm{DP}(i - 1, \textrm{next}(\textrm{arr}, j))$, where $\textrm{next}(\textrm{arr}, j)$ returns the new updated $\textrm{LCSdp}$ array after adding value $j$ at the end(we already have implemented this function). The base case of this recurrence is when $0$ elements are required to be added. In this case, we find the current LCS from the array $\textrm{arr}$ and return $1$ if this LCS is equal to $L$.

If we implement this DP recursively, we also need to memoize these $\textrm{LCSdp}$ arrays, for which we can use a map in C++. Let's see what is the complexity right now? First, we need to know how many distinct $\textrm{LCSdp}$ arrays can exist. Here comes the interesting property that in this array two consecutive elements can differ by at most 1. So, at each step, there could be a raise or not. So, we can say that $2^N$ is an upper bound on number of such distinct sequences.

Remember, complexity of a recursive memoized DP is product of different states with transition complexity. So our complexity is $N*2^N$(different states)*$K*N*log_{2}{2^N}$(transition). $N*K$ factor in transition because we calculate $\textrm{next}(\textrm{arr}, j)$ in $O(N)$, by adding each of the $K$ values. $log_{2}{2^N}$ is the retrieving cost of a state's value from the map. Total complexity right now is $O(N^3 * K * 2^N)$, which is quite high, we need to improvise our solution.

How do we reduce the complexity? Let's try to remove the use of map for memoization, if we remove map then complexity can be reduced by a factor of $N$. We need to have a compact representation of $\textrm{LCSdp}$ array. Instead of storing whole array, for each of the $N$ positions, we store whether there is an increment or not(remember the property?). So, now each $\textrm{LCSdp}$ array can be represented as a bitmask less than $2^{16}$. Hereby goes the factor due to memoization. Current complexity is $O(N^2 * K * 2^N)$. Its still not enough!

One more observation, we can make is that for a certain $\textrm{LCSdp}$ array $\textrm{arr}$, we can pre-calculate $\textrm{next}(\textrm{arr}, i)$ $\forall i \le K$. So, for all possible masks denoting $\textrm{LCSdp}$ arrays, for all possible values from $1$ to $K$, we pre-calculate the next mask. Doing this will take $O(2^N*K*N)$ and complexity of DP will have one more factor of $N$ removed. So overall complexity now will be $O(N*K*2^N)$ which is good enough.

For implementation, see setter's commented code.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester

DUALPAL - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Tasnim Imran Sunny
Tester:Istvan Nagy
Editorialist:Lalit Kundu

DIFFICULTY:

Hard

PREREQUISITES:

maths, backtracking

PROBLEM:

A number is called a Dual Palindrome if it's representation in bases B1 and B2 are both palindromes. Given two integers $B1$ and $B2$, Chef wants to find Dual Palindromes less than $2^{60}$. If there are more than $1000$ Dual Palindromes, then output the first $1000$ only(these numbers should be in base $10$).

EXPLANATION:

================

The cases where $B1$ and $B2$ are powers of same number then we have lots of Dual Palindromes, but since only the first 1000 palindromes are of interest the search will be finished quickly. The Dual Palindromes for other cases are very rare. The solution idea is backtracking with pruning.

Let's say we want to build a Dual Palindrome with $L$ digits(in base $B1$). For that, first we split the digits of base $B1$ palindromes in $4$ groups of lengths approximately $\frac{L}{4}$. Now, consider two sets of numbers $A$ and $B$(in base $B1$). Set $A$ contains all the numbers possible by considering the first quarter digits(i.e. first $\frac{L}{4}$ digits). Now, fixing first $\frac{L}{4}$ digits fixes the digits in last quarter also. Assume, digits are all $0$ in both middle quarters. This is the set of numbers called $A$.

Set $B$ contains the possible numbers by considering the first and fourth quarter as all $0$s and we define all possible ways to fill $2^{nd}$ quarter, so this fixed the $3^{rd}$ quarter too.

Adding any element from $A$ with any element of $B$, will always make a palindrome in $B1$. The problem is reduced to getting the pairs from $A$ and $B$ where their sum is palindrome in $B2$.

If you note, sets $A$ and $B$ have $2^{15}$ elements roughly in worst case.

Now, we have to construct the palindromes in $B2$. We use bactracking by placing digits from left to middle in our palindrome. At each node in the backtracking tree, we build two prefixes(say $x$ and $y$) from sets $A$ and $B$ such that current palindrome is $x$ ... $y$ ... $\textrm{rev}(y)$ ... $\textrm{rev}(x)$. Now, if there exists a pair of digits $a$ and $b$ such that $x$ $\textrm{concat}$ $a$ is present in set $A$, and $y$ $\textrm{concat}$ $b$ is present in set $B$(for implementing this setter has use Trie), and the new palindrome being formed in base $B1$ is a palindrome in $B2$, then we go ahead into the recursion tree with the new prefixes. Note, we are not exploring the exponential number of states in the backtracking recursion tree, because at each step we are pruning the subtrees by not going into unrequired nodes.

See setter's code for the implementation.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester

CARDLINE - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Tasnim Imran Sunny
Tester:Istvan Nagy
Editorialist:Lalit Kundu

DIFFICULTY:

Medium-Hard

PREREQUISITES:

dynamic programming, graphs, greedy

PROBLEM:

There are $N$ cards placed in a row, where every card has two numbers written on it, one on the top(array $A$) and one on the bottom(array $B$). The numbers are between $1$ and $N$(both inclusive). Every number is written on the top of exactly one card, and on the bottom of exactly one card as well.
Chef wants to rearrange the cards, such that the length of the longest common contiguous subsequence between the sequence formed by number written on top of the cards, and that formed by those written on the bottom is maximum. He can't modify the numbers written on any card and can't flip the cards, that is, for any card the number written on top remains at the top and the number written on bottom stays at the bottom. Find out the maximum possible length of the common contiguous subsequence.

QUICK EXPLANATION:

======================
Consider a single card as a node in the graph and then add edge between nodes $i$ and $j$ if $A_i = B_j$. In the graph built, break down cycles into chains and try to interleave these chains to form a common substring. For a set of chains, they can be interleaved only if size of each chain is either $m$ or $m+1$. Traverse over variable $m$ to calculate maximum possible answer. Answer for a certain $m$ can be calculated via DP.

EXPLANATION:

================

Note: We'll be using $0$-indexing of arrays in this editorial.

First observation should be that these cards have permutations written on them and problems involving permutations can usually be solved using dynamic programming + bitmasks, but constraints here are high. We can guess that a polynomial solution is required.

Let's try to think something on terms of graph. Maybe construct a bipartite graph where there are edges between two nodes if their value matches? Does it help? No, it doesn't because two values $A_i$ and $B_i$ are stuck together, they can't be moved around independently! So, why not consider a single card as a node in the graph and then add edge between nodes $i$ and $j$ if $A_i = B_j$. How does this graph look like? You can try some examples to see where are we arriving at. Let's consider the example,

7
4 2 6 5 3 7 1
4 5 6 3 2 1 7

The graph we've build looks something like:

 ____       1-----3
|    |       \   /
0____|        \ /
               4
 ____        ____
|    |      |    |
2____|      5____6

Let's observe the cycle with 3 edges. There are three cards with values $[2, 5]$, $[5, 3]$ and $[3, 2]$. If we place them in the same order we get

A = 2 5 3
B = 5 3 2

where substrings $A[1, 2]$ and $B[0, 1]$ are same. What if I put some more cards such that we get a formation of card numbers like $1-P-3-Q-4$($P$ and $Q$ are some other cards), now what happens? We get something like

A = 2 x 5 y 3
B = 5 a 3 b 2

Now, substrings $A[2,4]$ and $B[0,2]$ can be same if $a == y$. If we have two another cards with numbers $r$ and $s$ such that $B_r == A_s$, then we can place them instead of $P$ and $Q$ and our substrings will be matched. We have two such cards $5$ and $6$ with us.

Do you observe what is happening? Our partial sequence that gives us a common substring of length 3 is $S = [1, 5, 3, 6, 4]$. This happens because in the graph that we've built $1$ and $3$ are adjacent which matches values of $A$ and $B$ at indices $S_0$ and $S_2$ respectively. Similarly, values of $A$ and $B$ at $S_1$ and $S_3$ are matched because card numbers at those positions are adjacent in the graph. Again, at indices $S_2$ and $S_4$, cards which are adjacent are placed. We can complete our final sequence by adding remaining cards, before or after the current sequence but it doesn't matter as it doesn't contribute to the answer.

This is the main idea here. We are building a final single sequence(say $S$) of $N$ card numbers in such a way that for a certain $x$ and $j$, $S_j$ is adjacent to $S_{j+x}$, $S_{j+1}$ is adjacent to $S_{j+x+1}$, $S_{j+2}$ is adjacent to $S_{j+x+2}$ and so on. For that we break down cycles in chains of small lengths and then interleave multiple chain lengths to form a single sequence.

What about the criteria of length while interleaving? Can we interleave chains of arbitrary length together?
We should observe that for a certain chain all of its elements should be equally spaced(like in the above example for the chain ($1$-$3$-$4$) we placed them at a distance of $1$ from each other). You can see that if $S_0$ is adjacent to $S_x$, then $S_x$ should be adjacent to $S_{2x}$ and so on. Similarly, for the element at index $1$, $S_1$ should be adjacent to $S_{x+1}$ and so on.

Now, here is an interesting proposition:
If in a set of chains, length of any two chains doesn't differ by more than 1, it is possible to interleave them.
Here comes the greedy part. We know that for each element of a chain(except the last element), its next element should occur at equally spaced intervals. First, we place all chains of length $m+1$ and then all chains of length $m$ and now if we build our answer by putting elements from each chain one by one, this criteria will always be satisfied(Can you prove it?).

For example, three chains are

[1, 2, 3]
[6, 7, 8]
[4, 5]

If we arrange these cards like $[1, 6, 4, 2, 7, 5, 3, 8]$, then for each chain, its elements are equally spaced and each chain of length $\textrm{len}$ contributes $\textrm{len-1}$ values to the common substring(How?).

So, chains in a set should of length $m$ or $m+1$. Traversing over this variable $m$ till $N$ and taking maximum of all the cases will give us the answer. Consider, $m=1$. It is a special case because there is no next element in chains of length $1$. We have to handle this case separately. We can do that very easily by placing all chains of length $1$(which basically is a single card) adjacent to each other in our final solution.

The only thing now left is, for a given cycle length and a variable $m$, break cycle into chain lengths of $m$ or $m+1$ such that (total number of nodes included in the chains - total number of chains) is maximised. We subtract total number of chains, because each chain of length $\textrm{len}$ contributes $\textrm{len-1}$ to the answer. For this we employ DP :)

We define $\textrm{DP}(i, j)$ as the maximum number of nodes that can be covered by chains of length $j$ or $j+1$. Now, defining recurrence here is very easy:
$\textrm{DP}(i, j) = \textrm{max}(j - 1 + \textrm{DP}(i-j, j), j + \textrm{DP}(i-j-1, j)$.

Here is the commented pseudo code:

//this array contains cycle lengths
cycle[K]
final=0
for i=2 to N:
    curans=0    //answer for current value of i
    for j=1 to K:
        curans += DP(cycle[j], i)
    final=max(final,curans)
print final

This DP array can be precomputed to reduce the complexity. Total complexity that way would be $O(N^2)$.

Refer to setter's commented solution for implementation details.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester


COPS - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Devendra Agarwal
Tester:Surya Kiran
Editorialist:Amit Pandey

DIFFICULTY:

Cakewalk

PREREQUISITES:

None

PROBLEM:

There are 100 houses in a lane, numbered from 1 to 100. N cops are positioned in some houses. A cop's running speed is $h$ houses per second and he can run for at max $t$ secs. Find number of houses where a thief can hide such that he won't be caught by any of the cops.

QUICK EXPLANATION:

For each house and each cop, we can check whether the cop can reach the house or not by checking whether distance between them is less than or equal to maximum distance a cop can travel ($h * t$). If some cop can reach a house, then the house is unsafe otherwise it is safe.

The editorial explains three methods of finding number of safe houses having time complexities of $\mathcal{O}(H N)$, $\mathcal{O}(H \, log N)$ and $\mathcal{O}(H + N)$ respectively, where $H$ denotes number of houses (is fixed to 100 in our problem) and $N$ denotes the number of cops.

Explanation

For a particular house, we want to find out whether this house can be checked by some cop or not. We know that a cop can cover a maximum of $h * t$ inter-house distances in $t$ secs. So, if the distance between the thief's hiding house and cop's house is less than or equal to $h * t$, then the cop can catch the thief. We just need to check whether the current house can be reached by any of the cops or not. If yes, then it is not safe otherwise it is safe.

So, we can describe the solution succinctly as follows.

ans = 0
for each house from 1 to 100:
    safe = true
    for each cop houses from 1 to N:
       if (the cop can reach the house)
          safe = false
    if (safe) ans += 1

Clearly the above implementation of the problem will take $\mathcal{O}(100 * N)$ time.

Faster Solution

Let us say thief is currently at house $p$ and we want to check whether he will be safe in this house or not. If we can find the nearest cops in both directions of the lane from current house, then we just need to check whether these nearest cops in either direction can reach the house $p$ in time or not.

We will describe a method for finding nearest cop in forward direction faster than $\mathcal{O}(N)$ time. Backward direction can be handled similarly.

Let us can create a sorted array of houses of cops. We want to find the first element in the array having value $\geq p$. This can be done by using binary search over the array. Time complexity of this will be $\mathcal{O}(N)$ per search operation in array.

You can also find the same thing using $\mathtt{lower}$_$\mathtt{bound}$ in set in C++. set maintain a balanced binary search tree underneath it, which takes $\mathcal{O}(log N)$ time for each $\mathtt{lower}$_$\mathtt{bound}$ query.

So, this solution runs in $\mathcal{O}(100 * log N)$ time. Can we make it faster?

Even Faster Solution

We have to find $nextCopHouse$/$prevCopHouse$ information for each house faster. Let us see how can find $nextCopHouse$ information faster. Let us make a boolean array $isCop$ of size $100$ where $isCop[i]$ denotes that there is a cop in $i$-th house or not.

Now, we go from house number 100 to 1 and update the $nextCopHouse$ information by maintaining the position of latest house having cop in it.

latestHouseHavingCop = -1;
for house p from 100 to 1:
    if (there is a cop in the house):
        latestHouseHavingCop = p;
    nextCopHouse[p] = latestHouseHavingCop;

Time complexity of this solution is $\mathcal{O}(N + 100)$.

AUTHOR'S, TESTER'S SOLUTIONS:

setter's solution
tester's solution

SEQTOWER - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Devendra Agarwal
Tester:Surya Kiran
Editorialist:Amit Pandey

DIFFICULTY:

Medium-Hard

Problem:

You are given an array A consisting of prime numbers greater than 4.

Fun(S) = $A[S[1]]^{A[S[2]]^{...A[S[N]]}}$

You need to find the sum of the values returned by Fun(S) for every distinct sequence S.

Each element of S is an integer from 1 to N. Thus, there are $N^N$ possible sequences in all. As the values can be large, return it modulo M.

Solution:

Let us first solve a different problem to solve this problem

Problem Version 1 :

$A_i$ is a prime number greater than $M$ and $N <=1000$

Solution:

We will use recursive approach to solve this version of the problem.

First notice that $\phi(M)$ or $\phi(....\phi(M))))..)$ will always be coprime to all the numbers.

Recursive(L,M) returns an array where array[i] denotes denotes number of times i(less than M) appeared by using all N numbers for tower of length L.

You can find Recursive(Length-1,$\phi(Modulo)$) and find how many times value v ( which is less than $\phi(modulo)$ ) appeared .

You can use this info to calculate Recursive ( Length,Modulo)

How ?

For every possible v, we will apply on all $A_i$ as the base and calculate the modulo value again and update the counter of how many times the new value appeared.

Here is the psedo code for the idea:

for all possible v:
   for all i = 1 .. N:
      new_val = (A_i^v)%Modulo
      Times_Now[new_val] = Times_Now[new_val] + Times_Previous[v]

Complexity : $Modulo*N*Height$ = $N*M*log(M)$

Base Case : Modulo is 2 or 1 ( which ever is comfortable to you ) Or Length is 1.

Problem Version 2 :

Little Larger N (~ 1e5 ) and same as version 1.

Solution:

Now you can use this fact that atmost Modulo different values will be used.

Hence you can contract N values into M values and each appearing more than once.

for all i = 1..N:
   Number_of_times_appeared[A_i%Modulo] ++;

So, the Loop here changes to :

for all possible v {
   for all i =  0.. M-1 {
      new_val = (i^v)%Modulo
      Times_Now[new_val]=Times_Now[new_val]+Times_Previous[v]*Number_of_times_appeared[i]
    }
}

Time Complexity : $N*height + M*M*height = N*log(M) + M*M*log(M)$

Problem Version 3(Final Version):

Now the original problem

Solution:

Only thing which made our life simpler was that the $A_i$ was coprime to all the modulos in chain.

Now, we need to notice some interesting things here:

All $A_i$'s are prime numbers greater than 4

=>

$A_i ^ { any tower }$ % M where $A_i$ is not coprime to M

then M must be of the form $p^e * M_2$ , and $A_i$ must be $p$

Now notice that maximum value of e can be 5 for any p ( because $A_i$ > 4 , so smallest p is 5 and $5^6$ is more than 5000 )

Now if we use CRT and break the modulo in these two parts then one part is always 0. (which part ? )

Modulo of the tower from $p^e$ is always 0.(Except the Base Case which can be handled trivially)

Reason: Minimum number on the power will be 5, hence modulo with $p^e$ will always fetch 0 as result.

Now If we go back to CRT basics, we know that $a^b$ % M can be broken into $R_1 = a^b % M_1$ and $R_2 =a^b % M_2$

Here in our problem a is a prime number, $M_1$ is $a^e$

so, the solution from CRT is : $R_1*M_2*X_1 + R_2*M_1*X_2$

Here $X_1 = Inverse(M_2,M_1) , X_2 = Inverse(M_1,M_2)$

This equation reduces to : $R_2*M_1*X_2$ ( Because $R_1$ is $0$ )

Now this equation says $( a^b \bmod M_2 * M_1 *X_2 ) \bmod M$ is our final solution.

Note that $M_1*X_2$ is independent of $A_i$(or the a).

Now, the result $( (a^b \bmod M_2) * M_1 *X_2 )\bmod M$ is equivalent to saying $( (a \bmod M_2)*M1*X2 )^b \bmod M$

Reason for the second Part : Take Modulo $M_1$ , you will get $0$ , take modulo $M_2$ , you will get $(a^b) \bmod M_2$. This is the modulo pairs for the $M_1,M_2$ and by uniqueness of solution of crt , this solution is also correct

Now whats the benefit from this representation ?

We can contract our input which are not coprime by this formula : $(a \bmod M_2)*M_1*X_2$ and rest goes as it was in version 2 :)

AUTHOR'S, TESTER'S SOLUTIONS:

setter's solution
tester's solution

COMB4SUM - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Devendra Agarwal
Tester:Surya Kiran
Editorialist:Amit Pandey

DIFFICULTY:

Easy-Medium

PREREQUISITES:

None

PROBLEM:

Special Sum of 4 numbers (a, b, c, d) is defined as:

|a+b-c-d| + |a+c-b-d| + |a+d-b-c| + |c+d-a-b| + |b+d-a-c| + |b+c-a-d|

You have to find $\sum_{i=1}^{N} \sum_{j=i+1}^{N} \sum_{k=j+1}^{N} \sum_{l=k+1}^{N} Special Sum(A[i], A[j], A[k], A[l])$

Solution:

Before solving this problem we will be solving a different version of this problem.

Problem Version 1:

Given an array A, find the sum of all |a-b| where a and b are from different indices of A.

Solution for Version 1:

Sort the array $A$ in increasing order.

Now let us find the answer when $A_i$ is used.

$A_i$ is greater than $i-1$ elements and Less than $N-i$ elements.

Hence the value contributed by $A_i$ will be $2*( (i-1)*A_i - (N-i)*A_i )$

Now we can sum this up to find our solution.

Let us call this problem version as Function1(Array A) which will give us the solution of this version.

Main Problem:

SpecialSum(a,b,c,d) = (|(a+b)-(c+d)| + |(c+d)-(a+b)|) + (|(a+c)-(b+d)| + |(b+d)-(a+c)|) + (|(a+d)-(b+c)| + |(b+c)-(a+d)|)

You will get an intuition to find all N choose 2 sum and store in the array and call the above function to solve it but it will be wrong.

So, we will first find all N choose 2 sum and store them in an array.

Let us assume our original array was $A$, then

For i=1 to N:
  For j = i+1 to N:
     New_Array.Insert(A[i] + A[j])

What will be wrong in calling Function1(New_Array) ?

Lets go by an example 1 2 3 4.

We will be calling |(1+2) - (1+3)| in some stage, which was not required by specialsum definition.

So, How to eliminate those cases ?

|(a+b)-(a+c)| = |b-c| will be coming exactly N-2 times. [ Reason: There will be N-2 different indices for selection of a ]

Hence our answer will be Function1(New_Array) - $(N-2)$*Function1(A)

AUTHOR'S, TESTER'S SOLUTIONS:

setter's solution
tester's solution

UTMOPR - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author: Ankit Srivastava and Uttam Kanodia
Tester: Roman Rubanenko
Editorialist: Amit Pandey

DIFFICULTY:

Cakewalk

PREREQUISITES:

Basic programming

PROBLEM:

Given an array of $n$ integers, you have to do the following operation $K$ times: Insert a number in the array which is strictly greater than current sum of the array. You have to find whether the last number inserted is even or odd.

QUICK EXPLANATION:

As the value of $K$ is small, we can keep inserting smallest possible numbers at each step and print the $K^{th}$ number modulo $2$.

EXPLANATION:

This problem can be solved by simulating the operation given in the problem.

First find the sum of the given array($A$) . This can be done in $O(N)$ time using a single loop. As we have to print the $K^{th}$ element to be inserted (modulo $2$), we can replace $S$ by $S\ \% \ 2$.

S = 0;
for(int i=0; i< n; i++)
    S = S + A[i];
    S = S%2;

Now make an array $B$ of size $(K+1)$, $B_i$ will denote the $i^{th}$ element to be inserted, and $B_K$ will be our required answer. At any step, if parity of the sum of the elements of array is "even", parity of inserted element will be "odd".

B[1] = (S + 1) % 2 ;   // we will insert the smallest possible number at each step
total_sum = 0;
for(int i=2 ; i< K ; i++)
{
    total_sum = (total_sum + B[i-1]);
    B[i] = (total_sum + 1) % 2; // insert a number greater than current sum of the array.
}

Finally we can output $B_K$. The time complexity of the whole code will be $\mathcal{O}(N + K)$.

Another solution
Let us say that sum of the array $A$ is even. The next inserted element will be odd, now sum of array will be odd, so next inserted element will be even, now sum of array becomes odd, so we will insert an even number, and so on. So we can generalize that if sum of array is even, then for $K = 1$, last inserted number will be odd, otherwise it will be even.

Now, we will consider the case in which sum of the array $A$ is odd. The next inserted element will be even, now sum of array will become odd, so next inserted element will be even, now sum of array will be odd, we will add another even number, and so on. So we can generalize that last inserted number is always even in this case.

So finally, we can obtain the following simple solution.

Compute sum of array.
If K = 1:
    if sum is even:
        print "odd"
    else:
        print "even"
else:
    print "even"

Solution:

Setter's solution can be found here
Tester's solution can be found here

ANKPAREN - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author: Ankit Srivastava and Uttam Kanodia
Tester: Roman Rubanenko
Editorialist: Amit Pandey

DIFFICULTY:

Easy-Medium

PREREQUISITES:

Basic programming

PROBLEM:

Given a string containing '(' and ')' only. Find the longest such subsequence of the given string that is non-regular. Amongst all such distinct answers, output the lexicographically $K^{th}$ amongst them.

QUICK EXPLANATION:

If the given string in not balanced, then the string itself is the largest non-regular(unbalanced) pattern. On the contrary, if the given string is regular(balanced), then all subsequnces having length $(N-1)$ will be non-regular and there is a pattern in their lexicographic ordering.

EXPLANATION:

The problem can be broadly classified into two cases:

Case I: Given parenthesis string is not balanced, which can be checked using stack data structure described here. In this case, the largest unbalanced sub-sequence will be then the given string itself. So if $K=1$, then the answer will be the given string, $-1$ otherwise.

Case II: Given parenthesis string is the balanced one. Consider that $L$ is the length of the given string, then there will $L$ sub-sequences of length $(L-1)$, and each of them will be unbalanced. This is because, in any sub-sequence, number of opening and closing parenthesis will not be the same.

How to find the number of distinct unbalanced sub sequences?

Consider a string $S$ = "(())", what will be number of distinct unbalanced sub-sequences? it can be easily claimed that if we delete $S[0]$ or $S[1]$, we will get same string i.e. "())". So, it can be seen easily that if we delete any character from a contiguous chunk of the characters, we will get same unbalanced sub-sequence. It can be formally written as follows:

Consider the any contiguous chunk of same characters in the given string, Suppose $S[i] = S[i+1] = S[i+2] =\ ....\ = S[j] =\ '('$ or $')'$. If we delete any character between $i^{th}$ and $j^{th}$ positions (both inclusive), it will produce the same sub-sequence, because deleting any of them will replace $(j-i)+1$ number of same characters by $(j-i)$ number of same characters. So number of distinct sub-sequences of length $(L-1)$ will be number of different contiguous chunks of same characters. For example, string $(())((()))$ will have $4$ distinct sub-sequence of length $9$, and each of them will be unbalanced.

How to do lexicographic ordering of those sub-sequences?

Suppose that the string which we generate by deleting a character from the $i^{th}$ chunk (0-indexed) is $L_i$. As our given string is balanced, it will consist of one or more opening parentheses and one or more closing parentheses alternatively (starting with opening). So, to produce $L_{2n}$ we need to delete an opening parenthesis, and to produce $L_{2n+1}$, we need to delete a closing parenthesis. Now, let me claim that the lexicographic ordering:

$$L_{2i+1} < L_{2j+1}, \hspace{2 mm} L_{2i} > L_{2j} \hspace{2 mm} for \hspace{2 mm} (i < j) $$ $$L_{2i+1} < L_{2j} \hspace{2 mm} \text{for all} \hspace{2 mm}(i,j) $$

So for string $S = ''(())()((()))(())"$, the lexicographic order will be $L_1 < L_3 < L_5 < L_7 < L_6 < L_4 < L_2 < L_0$. To produce lexicographically $3^{rd}$ string we need to produce $L_5$ by deleting any of the bold characters : "(())()((()))(())".

Proof: Consider the proof $L_{2i+1} < L_{2j+1},\hspace{2 mm} \forall \hspace{2 mm} (i < j)$. Others can be proved in the same manner.

Consider that the $i^{th}$ chunk has $A_i$ number of characters. Now consider the $(A_1 + A_2 + .... A_{2i+1})^{th}$ character in $L_{2i+1}$ and $L_{2j+1}$, it will be ')' in $L_{2j+1}$, as $i < j$, and it will remain the same as in the original string, but it will be '(' in $L_{2i+1}$ and all previous characters will be the same in both of the strings. As opening parenthesis is lexicographically smaller than closing parenthesis, hence $L_{2i+1} < L_{2j+1}$.

Solution:

Setter's solution can be found here
Tester's solution can be found here

ANKGAME - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author: Ankit Srivastava and Uttam Kanodia
Tester: Roman Rubanenko
Editorialist: Amit Pandey

DIFFICULTY:

Easy-Medium.

PREREQUISITES:

Game theory and Combinatorics.

PROBLEM:

A game is played with the rule that a non-zero number of the stones must be removed from the first non-empty pile. Find the number of permutations of the piles, in which the first player has a winning strategy.

QUICK EXPLANATION:

Find a way to check if a given permutation is the winning permutation, followed by finding the number of permutations which satisfy the given condition.

EXPLANATION:

The problem can be solved using various claims.

Claim 1: If each pile contains exactly $1$ stone. Now, if number of piles is even, then second player will win. Otherwise, first player will win.

Reason: The reason being that each player will have exactly one way of making a move, i.e. emptying the current pile.

Claim 2: If the first pile contains more than one stone, then first player will always win.

Reason: Suppose that piles are numbered as $1,2,3...N$. Number of stones in piles are given as $A_1,A_2,....A_N$ with the condition $A_1 \ge 2$.

Case 1: Suppose in piles $A_2,A_3,...A_N$, first player has winning strategy, then first player will remove $A_1-1$ number of stones from the first pile and second player will be enforced to remove remaining $1$ stone. First player will have winning strategy on remaining piles.

Case 2: Suppose in piles $A_2,A_3,...A_N$, first player doesn't have winning strategy, then first player will empty first pile in single move. So, when game will arrive as pile $2$, second player will not have the winning strategy, hence first player will have winning strategy.

Claim 3: Now we can claim very easily that first player will win if permutation is in such a way that $A_1 = 1, A_2 = 1,... A_x = 1, A_{x+1} != 1$, and $x$ is an even number, because when the game will arrive at pile number $(x+1)$, first player will be making first move and he will win according the points given above.

How to count number of permutations such that number of 1's in the beginning is even?

Suppose count of $1$'s in the array $A$ is $M$. Each distinct number of array $A$(except 1) is in array $B$, i.e., $B_1, B_2,...B_K$, and count of $B_i$ in array $A$ is $cnt[B_i]$.

Now count the number of permutations in which number of 1's in the beginning is at least $x$. To do that, keep $x$ $1's$ in the beginning and permute rest of the numbers.

$$W(x) = \frac{(N-x)!}{(M-x)!\ cnt[B_1]!\ cnt[B_2]!\ ....\ cnt[B_K]!} $$

$$\text{Consider } K = \frac{1}{cnt[B_1]!\ cnt[B_2]!\ ....\ cnt[B_K]!} $$

$$So, W(x) = \frac{K\times(N-x)!}{(M-x)!} $$

Number of permutations in which number of $1's$ in the beginning is exactly $2r$.

$$ Ways(2r) = W(2r) - W(2r+1)$$

So, number of permutations in which numbers of 1's in the beginning is even:

$$ \text{Number of permutations} = \sum_{r=0}^{2r+1 \le M} Ways(2r) $$

$K$ is a constant which can be calculated in $O(N)$ time, and we can calculate it in the beginning. So, Number of permutations can also be calculated in $O(N)$ time.

Solution:

Setter's solution can be found here
Tester's solution can be found here

ANKMARKS - Editorials

$
0
0

PROBLEM LINK:

Practice
Contest

Author: Ankit Srivastava and Uttam Kanodia
Tester: Roman Rubanenko
Editorialist: Amit Pandey

DIFFICULTY:

Medium

PREREQUISITES:

Matrix Exponentiation

PROBLEM:

There are $N$ students and the marks awarded to any student should be linear combination of the elements of a given set, while satisfying other constraints as well. Find the minimum average of the marks which can be allotted to the students. In other words, find the minimum possible class average.

EXPLANATION:

There are various steps in solving the given problem. Let's go through them one by one.

Let us call the given set of marks as $S$. First of all, let's make a function $check(x)$ which will tell if a given number $x$ can be awarded as a score to any of the students. Since the score is a linear combination of the elements of $S$, a score $x$ can be allotted iff any of the marks among $x-S[0], x-S[1], .... , x-S[k-1]$ can be allotted, or if $x=0$, the base case. Thus, $\forall x>0$,

$$check(x) = check(x-S[0]) \hspace{2 mm}or\hspace{2 mm} check(x-S[1]) \hspace{2 mm}or\hspace{2 mm} ... \hspace{2 mm}or \hspace{2 mm}check(x-S[k-1]) $$

It is given that the answer to the problem will be at most $2^{52}$, so we need to check up to $2^{52} \times 1000 \approx 2^{62}$, which is a very large number and can be checked using matrix exponentiation technique. This method will take $O(50^3 \times \log{x})$ time. There is another excellent way of computing $check(x)$, which uses Dijkstra's Algorithm. It has been described here in a nice way. See tester's code for this approach.

Now, for any given score, we can check if it can be allotted to a student, or not. So, let's make a list which contains all the scores which can be allotted. As we have to find the minimum average, we will try to allot minimum possible marks to each of the students. Minimum marks which can be allotted is $0$. Second minimum marks which can be allotted is the minimum element of the set $S$. Now, suppose someone has received $x$ marks, the guy which is located next to him should be allotted more than $2x$ marks. So, we will keep checking if $2x+1,2x+2,...$ can be allotted and allot the minimum possible marks. Now, we can make a allotment list $L$, which is the list of marks to be allotted to all the students in the class. $L[i]$ can be calculated as follows:

$$L[0] = 0, \hspace{2 mm} L[1] = min(S), \hspace{2 mm}L[i] = min(x) \hspace{2 mm} \text{such that} \hspace{2 mm} x \ge 2L[i-1] +1 \hspace{2 mm} \& \hspace{2 mm} check(x) = true .$$

Now, final part of the solutions is the calculation of the exact score allotted to each student:

Pick each of the local minimum elements of the favorite array one by one. For each local minimum, allot the corresponding student $0$ marks. Keep going to the right of it as long as the favorability is increasing, and keep allotting the next element of the list $L$. Repeat the process in the left of the local minimum. Now, there will be multiple allotments at the same position corresponding to the each of the local minimum. To satisfy all conditions, every student will receive maximum marks among all the marks allotted corresponding to each local minimum of the array.

Once every student has received their marks, average calculation is easy.

Solution:

Setter's solution can be found here
Tester's solution can be found here


ANKNIM2 - Editorials

$
0
0

PROBLEM LINK:

Practice
Contest

Author: Ankit Srivastava and Uttam Kanodia
Tester: Roman Rubanenko
Editorialist: Amit Pandey

DIFFICULTY:

Medium

PREREQUISITES:

Fast Fourier Transform.

PROBLEM:

Given an array of $N$ integers. You have to find count of all subarrays of size $m$, such that if a Nim Game is played on the subarray, second player will win. Do it for all possible values of $m$, $1 \le m \le N$.

EXPLANATION:

It can be claimed using Nim Game theory that second player will win the game if $XOR$ of the selected subarray is $0$. We can find XOR of any subarray in $O(1)$ time by creating a prefix XOR array.

$$ preXOR[0] = 0 \hspace{3 mm}\& \hspace{3 mm}preXOR[i] = A[0] \oplus A[1] \oplus \cdots \oplus A[i-1]$$

$$ A[i] \oplus A[i+1] \oplus \cdots A[j] = preXOR[i-1] \oplus preXOR[j]$$.

Now, let me present an $O(N^2)$ solution for the problem.

answer[n] = 0;
for i in range(0,n):
    for j in range(i+1,n):
        if preXOR[i] == preXOR[j]:      //subarray having size (j-i) has XOR 0.
            answer[j-i]++;

Consider a number $k$. If it appears $l$ times in the $preXOR$ array, then there will be $^lC_2$ subarrays in array $A$ whose XOR is zero. We can create an array corresponding to indices of $k$ in $preXOR$ array, and call it $S$. It means $preXOR[S[i]] = k$ for all $i < l$.

      for i = 0 to l-1:
          for j= i+1 to l-1:
             ans[j-i]++;       // there is a subarray of size (j-i) having XOR 0.

It can be explained further,Consider that preXOR array is $[1,2,3,1,1,4,1]$, then the array $S$ for $k=1$ will be $[0,3,4,6] \text{(0 based indexing)}$.

The above solution can take up to $O(N^2)$ time in the worst case, as size of $S$ can be $O(N)$. To improve it, we can do the following modifications:

1) If size of the array $S$ is lesser than $\sqrt{N}$, then we can use brute force as given above.

2) If size of the array $S$ is greater than $\sqrt{N}$, then the above solution will take more time. So, we can use the FFT to optimize the solution to time $Nlog(N)$.

Number of sub-arrays of size $K$ having XOR $0$, will be coefficient of $x^K$ in following polynomial:

$$(x^{S[0]} + x^{S[1]} + \cdots + x^{S[L-1]}) (x^{-S[0]} + x^{-S[1]} + \cdots + x^{-S[L-1]})$$

The powers of $x$ in the above polynomial are negative as well, therefore we do a small modification in above polynomial to make all the powers positive. It will be equivalent to the coefficient of $x^{N+K}$ in the following polynomial:

$$(x^{S[0]} + x^{S[1]} + \cdots + x^{S[L-1]}) (x^{N-S[0]} + x^{N-S[1]} + \cdots + x^{N-S[L-1]})$$

Which can be done in $O(Nlog(N))$ time using Fast Fourier transform. The FFT will give answer corresponding to all possible value of $m$ altogether.

We can repeat the above procedure for each distinct element $k$ of $preXOR$ array. The total count of subarrays corresponding to each value of $m$ will be the count of subarrays of size $m$ for each distinct value of $k$.

Worst case complexity of the above procedure will be $O(N \sqrt{N} \log{(N)})$.

Problems to solve:

  1. FARASA

Solution:

Setter's solution can be found here
Tester's solution can be found here

CANDLE - Editorial

$
0
0

PROBLEM LINKS

Practice
Contest

DIFFICULTY

EASY

EXPLANATION

The answer will always be either a repdigit (a number composed of repeated instances of the same digit) or a power of 10. We find the smallest power of 10 that cannot be expressed, and for each digit we find the smallest repdigit that cannot be expressed, and take the smallest of these.

TESTER'S SOLUTION

Can be found here.

TANSWTCH - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Ayush Jaggi
Tester:Anurag Anand
Editorialist:Anurag Anand

DIFFICULTY:

CAKEWALK.

PREREQUISITES:

Ad Hoc

PROBLEM:

Given the configuration of a sequence of switches as a string, we need to toggle some of the switches such that all the 'Off' switches appear before 'On' switches.

QUICK EXPLANATION:

We can iterate over the number of 'Off' switches in the final sequence and find the number of toggles required to achieve that configuration.

EXPLANATION:

Let $S$ be the input string. Let $N$ be the length of $S$. Let us assume the characters of the string are indexed from $0$ to $N-1$.
So, if $S$ = "$ONO$", then $N =3$, $S[0]$ = '$O$', $S[1]$ = '$N$' and $S[2]$ = '$O$'.

'$O$' denotes 'Off' and '$N$' represents 'On'. We'll use '$O$' and '$N$' from now onwards.

Let $R$ be the string obtained from $S$ after performing some toggles such that in $R$, all '$O$' characters occur before '$N$'. Let us consider the count of '$O$' in $R$ after toggling some switches. It can be anything between $0$ to $N$. If the count of '$O$' is $K$, then $R[i]$ = '$O$' for $0 \le i < K$ and $R[i]$ = '$N$' for $K \le i < N$. So, if we fix the count of '$O$' to be $K$, then for all index $i$ where $S[i] \ne R[i]$ we'll require one toggle. So, the number of toggles required is number of index $i$ such that $0 \le i < K$ and $S[i]$ = '$N$' or $K \le i < N$ and $S[i]$ = '$O$'. We can iterate over $K=0$ to $K=N$ and find the number of toggles required for each $K$. The minimum among all will be answer. You can refer to the following pseudo code.

ans = INFINITY for K = 0 to N count = 0 for i = 0 to K - 1 if S[i] == 'N' count = count + 1 endfor for i = K to N - 1 if S[i] == 'O' count = count + 1 endfor ans = min(ans, count) endfor

The time complexity of this solution is $O(N^2)$ for each test case.

ALTERNATIVE SOLUTION:

There is also a solution with time complexity $O(N)$. At each point of time, we only need the count of '$N$' for some prefix and the count of '$O$' for some suffix of $S$. Let $countOff$ be the total count of '$O$' and $countOn$ be the total count of '$N$' in $S$. For $K=0$, all '$O$' must be converted to '$N$', hence the number of toggles needed = $countOff$. Let us consider $K>0$ case. Now, we iterate over the characters of $S$ from $0$ to $N-1$. We maintain $prefOff$ and $prefOn$ which are the count of '$O$' and '$N$' respectively, encountered till now. Number of toggles needed for a given $K$ = count of '$N$' from $i=0$ to $i=K-1$ + count of '$O'$ from $i=K$ to $i=N-1$ which can also be written as count of '$O$' from $i=0$ to $i=K-1$ + $countOff$ - count of '$N$' from $i=0$ to $i=K-1$, or $prefOn + countOff - prefOff$.

countOff = 0, countOn = 0 for i = 0 to N - 1 if S[i] == 'O' countOff = countOff + 1 if S[i] == 'N' countOn = countOn + 1 endfor

ans = countOff prefOff = 0, prefOn = 0 for i = 0 to N - 1 if S[i] == 'O' prefOff = prefOff + 1 if S[i] == 'N' prefOn = prefOn + 1 ans = min(ans, prefOn + countOff - prefOff) endfor

AUTHOR'S AND TESTER'S SOLUTIONS:

Author's solution can be found here.
Tester's solution can be found here.

Cheating In SOPC2.0

TLG - Editorial

$
0
0

PROBLEM LINK:

Practice

Author:ADMIN

Editorialist:SUSHANT AGARWAL

DIFFICULTY:

EASY

PREREQUISITES:

Basic looping,Arrays

PROBLEM:

At the end of each round the leader and her current lead are calculated. Once all the rounds are over the player who had the maximum lead at the end of any round in the game is declared the winner.

EXPLANATION:

Create two arrays(Player1-Stores the scores of player 1 in all the rounds)[a1,a2,a3....an] and (Player2-Stores the scores of player 2 in all the rounds)[b1,b2,b3...bn].

Create a third array "Lead" such that the i'th element of Lead is ((a1+a2...+ai) - (b1+b2...bi)). Create a fourth array "modulus lead" such that the i'th element of this array is the modulus of the i'th element of "Lead".

Find the maximum element of "modulus lead".This is the maximum lead attained by the winner.If the element in the corresponding position of "lead" is positive then player 1 is the winner,otherwise player 2 is.

EDITORIALIST'S SOLUTION:

Editorialist's solution can be found here.

Viewing all 40121 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>