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

BTMNTREE - Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Igor Barenblat
Tester-Misha Chorniy
Editorialist-Abhishek Pandey

DIFFICULTY:

MEDIUM-HARD

PRE-REQUISITES:

Segment Tree + Lazy Propagation, Dynamic Programming, DP on Trees, Euler Tour of Tree

PROBLEM:

Batman starts from vertex $u$. At each second, he can choose to catch a robber whose power is strictly less than his'. Also, the path of robber must lie COMPLETELY inside the path of batman from his current vertex to the chosen vertex. His power then increases by $t$. We need to find maximal achievable power of batman if he catches robbers optimally.

QUICK EXPLANATION:

Key to AC- This question was a test of DP on trees along with Segment Tree and Lazy Propagation. Practice of such questions was the key.

Let $dp[v]$ be the maximum power obtained if we are at vertex $v$. We use segment tree along with lazy propagation to update and maintain the table. We narrow down the solution to $3$ cases-

  • When $u$ is parent of $v$
  • When $v$ is parent of $u$
  • Neither of above holds

We can easily obtain the range of update using $Euler$ $Tour$ of the tree and examining cases when its possible for batman to choose an appropriate vertex $g$ to catch robber, and when not.

EXPLANATION:

This was the hardest problem of the set. It is expected that the pre-requisites are clear. The editorial will have $4$ segments (please get the pun), one for pre-calculations done, one discussing the segment tree, other handling updates and lazy propagation along with case analysis, and last one DP. @mgch (tester's) solution will be referred to implementation.

1. Pre-calculations-

We intitialize the dp table with $-\infty$ initially, and do a DFS for Euler tour of tree. Euler Tour will store the time when we enter a node and its sub-tree (in $in[u]$), and when we exit it (in $out[u]$).

We initialise the dp table by setting $dp[s]=p$ where $s$ is the starting vertex and $p$ is initial power of Batman.

2. Building Segment Tree-

What do we store in node? As said earlier, the tree is built on array $dp[]$, so in each node (say $tree[v]$) we will store answer (i.e. $max(dp[l..r]$), or more formally-

  • if $l==r:$ tree[v] = dp[l];
  • else tree[v]=max(tree[2v], tree[2v+1]);

Code for building the tree is in tab below. Compare it with what you can come up with after reading the explanation!

View Content

3. Query, Update and Lazy Propagation-

We must keep the following condition in mind-

Let's denote Batman's current vertex by s (s=si initially). To catch the robber, Batman must choose a vertex g such that each vertex on the simple path between x and y (inclusive) lies also on the simple path between s and g (inclusive). If it is impossible to choose a vertex g so that this condition is satisfied, Batman cannot catch this robber.

Lets analyze it in light of $3$ cases analyzed in Quick Explanation Section. Let me refer to $x$ and $y$ as $u$ and $v$ respectively as its more conventional :).

  • $u$ is parent of $v$- To catch this robber, Batman must NOT be at a node which allows entry inside the simple path (from $u$ to $v$) from points other than $u$ and $v$. Else he will not be able to cover ALL nodes in simple path from $u$ to $v$. (If it is possible to catch the robber, we will update value of $dp$ table at ALL nodes from where Batman can chose an appropriate vertex $g$. To formalize, we will update all nodes where batman can choose a destination, i.e. sub-tree of $v$ if a destination can be chosen there, or everything outside sub-tree of $w$ ($w$=$u's$ first son lying in path from $u$ to $v$) if an appropriate destination can be chosen..
  • If $v$ is parent of $u$. - Dealt exactly same as above.
  • Neither of above holds $\implies$ Both have a common parent. Hence we can go from sub-tree of $u$ to sub-tree of $v$ and vice-versa. Both these sub-trees must be updated.

In above, remember that the vertices of $destination$ are updated! Recall what are we storing in $dp[v]$. "Let $dp[v]$ be the maximum power obtained if we are at vertex $v$."

The "syntax" to query is given below (i.e. how to call query function + Case analysis).See if it matches with what you understood!

View Content

With that clear, how do we exactly query? Thats even easier! Recall the standard query functions. The only change here is that we a re doing lazy propagation right now. Lets analyze what will be the cases/steps in query function.

  • If out of range, return $-\infty$
  • Update the node if needed.
  • If it lies completely in range, return the node.
  • If not in range, query in ranges $[L,Mid]$ and $[Mid+1,R]$ and return the maximum obtained answer. Make sure to push updates/do lazy updates before getting answer!
View Content

For reference, tester's implementation of push function is given below-

View Content

The only thing left is now update function. I think if you've read my previous segment tree editorials, it must be getting like "Something is repeating again and again." Yes! Thats the first sign of improvement! Try to make the update function on your own w.r.t. given query functions and syntax. A commented version is given in tabs below-

View Content

4. Dynamic Programming-

Finished.

??
?????
$??????????$

What?

Dynamic Programming says "Remember previous values" and I say "Remember the previous explanation." :p. how many of you noticed that this part is already discussed in $3$ segments above? Some exclusive parts were, in finding LCA of the two nodes $u$ and $v$ (Refer to link in pre-requisites) and our segment tree :).

SOLUTION:

The setter and tester's code are given below. If the links dont work, please view code in the "View content" tab. I pasted code their only for your comfort :). Tester's code is commented and discussed in editorial.

Setter

View Content

Tester

View Content

Editorialist Solution will be put on demand :)

$Time$ $Complexity=O(MlogN)$

CHEF VIJJU'S CORNER :D

1. Give a brief note on uses of Euler Tour in Competitive coding! EXPLORE!! (25 karma for decent answer :) ). [I can myself give notes, but I want you guys to explore and contribute as well. :D )

2. Author's Solution- He worked hard to write it and hoped you love it!!

View Content

3. ????????????????????????????

View Content

4. Test case Bank-

View Content

5.Related Problems-


NUMCOMP - Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Igor Barenblat
Tester-Misha Chorniy
Editorialist-Abhishek Pandey

DIFFICULTY:

Cakewalk

PRE-REQUISITES:

Basic Maths of power and exponents, if-else statements

PROBLEM:

Given $a,$ $b$ and $n$ , we need to tell if ${a}^{n}>{b}^{n}$ or not.

QUICK EXPLANATION:

Key to Success: While its a cakewalk question, and everyone gets AC, edge is gained over others by implementing the correct solution quickly. A proper insight of conditions is the key to success here.

There are many ways to do the question. As I said, a good insight in condition helps. We simply make cases for-

  • if a==b or (n is even AND abs(a)==abs(b))
  • if n is even - we check if a is greater or b
  • if n is odd, compare a and b and print corresponding answer.

Try making a solution using these if this question gave you a problem during contest!!

EXPLANATION:

We will have a single section in this editorial, and will refer to tester @mgch's solution for reference.

Full Solution-

"OMG SO MANY CONDITIONS. WTF?! $A$ AND $B$ CAN BE NEGATIVE AS WELL!!!!!!!!!!! HOLY COW INFINITE IF-ELSE WTFFFFFF RIP EVERYTHING RIP GGWP I M DEAD"

If you are one of those who have similar problems, then this editorial is just for you. There are multiple ways to tackle this statement, but I will discuss tester's approach here as I find it elegant :)

We will, this time, use Divide and conquer. Divide the cases into sub-cases until they are easy to conquer!! xD

Lets formalize our cases. I assume you know about absolute function ( abs() ) of C++. If not, check tab below.

View Content

a. When will answer be 0?

Simple. If $A==B$ $OR$ If $(N$ is even and $abs(A)==abs(B))$. Only these cases are possible.

We hence get the following condition-

If A==B OR (N is even AND abs(A)==abs(B) ): Print(0);

Good, we have done $33\%$ of the problem. But making cases more cases like, when will answer be $1$ or when will it be $2$ is tedious. What is a bugging thing right now? Oh yes! The signs are of $A$ and $B$ may not be same. Lets deal with it.

If $N$ is even, then we dont care of signs. Thats a great case. We can easily frame this condition now-

If N is EVEN: Print 1 if abs(a)>abs(b) Print 2 if abs(b)>abs(a)

Now, we are left with cases where $N$ is odd. Signs will matter here, so lets deal with it now. In case you feel "Now we are left with cases where $N$ is odd" a too sudden conclusion, the tab below is for you :).

View Content

Now, if $N$ is odd, I said signs matter. Yes, they 'matter' a lot indeed :). Hence, ignore them! Nobody should matter so much xD. Our next condition is-

If N is odd: //automatically implied Compare if A>B or B<A and print corresponding answer.

We are DONE with this question after this! :D. A question for you, why did we not care for signs here?

Any bonus content is in Chef Vijju's Corner.

SOLUTIONS:

It takes time for @admin to link solutions and get the links working. If they arent working for you, please open the tab below to check the codes.

Setter

View Content

Tester

View Content

Editorialist's solution will be put on demand.

$Time$ $Complexity=O(1)$ per test case.

CHEF VIJJU'S CORNER :D

1. Why not care for signs if $N$ is odd?

View Content

2. Why we dont care to calculate ${a}^{n}$ and ${b}^{n}$

View Content

3.Test Case Bank-

View Content

4. Related Problems-

SONYASEG - Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Igor Barenblat
Tester-Misha Chorniy
Editorialist- You wont believe who this guy is when you click here

DIFFICULTY:

Easy

PRE-REQUISITES:

Combinatorics, Finding $^{n}C_k\% p$ using Fermat's Little Theorem, Data structures like multiset.

PROBLEM:

Find number of ways to choose $K$ out of $N$ segments such that their common intersection is empty. Common intersection, in other words, means $L_1 \cap L_2 \cap ... \cap L_k = \phi$ $i.e. (empty/null)$. Print answer modulo ${10}^{9}+7$

QUICK EXPLANATION:

Key to AC- Its very easy if you have some practice in combinatorics, else the intuition may seem tricky. Finding number of violating cases was easier than finding number of good ones. Calculating answer as $Ans=Total$ $Cases-Bad$ $Cases$. Total cases, obviously, is $^{n}C_k$.

We pre-calculate the inverse and factorial of required numbers to calculate $^{n}C_k$ in $O(1)$ time. We can easily maintain a $multiset$ (to maintain order). We can easily formalize when all $K$ elements intersect as if $min(R_1,R_2,..,R_{k-1}) \ge L_i$ where segment $\{L_i,R_i\}$ is the segment under consideration. After this, its simple calculation of $^{n}C_k$. We will discuss derivation under explanation section.

(WHAT? You want me to give away everything in Quick Explanation? xD.)

EXPLANATION:

This editorial will have a single section. Its assumed that you went through how to calculate $^{n}C_k$ as we wont be discussing this in detail in official part. We will simply see the intuition and derivation of formula. I will give whatever links I can for $^{n}C_k$ in Chef Vijju's Bonus Corner :). We will refer to @mgch (tester's) solution for implementation.

1. How to deduce that ans is calculated by finding number of bad combinations and subtracting them from total combinations?

This comes with practice. Really! It will seem something trivial to someone who is well versed with such questions. However, if you want what concrete steps we can analyze are-

  • Easy formalization of condition when all $K$ segments intersect.
  • Total ways are easy to find. Simply $^{n}C_k$
  • We will see below that a direct formula exists to find number of violating segments.

2. I have taken the input. What next?

Well, whats next? We solve the question! The very first thing to do is, we sort the segments. We sort the segments in increasing order of $L_i$. If $L_i$ are same, then the segment with larger $R_i$ comes first.

Why $R_i$ in descending order? Simple, because if $L_i$ are same, then inserting larger segment first helps us to easily find if $k$ segments intersect. (Why?Q1)

Now we will maintain a multiset of lines. Multiset is used as it keeps them in sorted order. There are many implementations on what to store and how to use. Giving details of most easy one, I quote "we need not make a custom data type, merely storing the end points of lines can do." (Why?Q2) A hint is given in tab below.

View Content

The multiset will store the $R_i$ in ascending order. Now, when do $2$ horizontal lines intersect? Can you try framing conditions on when they interesect and when they dont?

View Content

Now, we will follow a straightforward procedure-

  1. For every segment $\{L_i,R_i\}$ do the following-
  2. WHILE multiset is not empty, and the lines dont intersect- Delete the line with smallest $R_i$ from multiset and check again.
  3. Number of violating ways using this segment $\{L_i,R_i\}$ are $^{p}C_{k-1}$ where $p=size \space of \space multiset$
  4. Insert end-point of this line in the set.

Lets discuss the intuition behind it. Step $1$ is simple looping. Step $2$, we discussed above when line intersect and when they dont. We need all $k$ lines to intersect for a way to be violating. Hence, if $i'th$ lines doesn't intersect, we delete the line with smallest $R_i$ from multiset. Now, either the multiset is empty, or we have number of lines which intersect with given $i'th$ line. (Why?Q3)

Now, what we have in multiset is a set of lines which intersect with $i'th$ line. We must choose $i'th$ line, and are free to choose rest $k-1$ lines from the multiset. If, thus, size of multiset is $p$, then number of ways of choosing $k-1$ lines is simply $^{p}C_{k-1}$. A simple code for above is given below-

    multiset < int > f;
    int bad = 0;
    for (int i = 1; i <= n; ++i) {
        while (!f.empty() && *f.begin() < p[i].first) {
            f.erase(f.begin());
        }
        bad = (bad + 1LL * comb(f.size(), k - 1)) % MOD;//comb(a,b)=aCb
        f.insert(p[i].second);
    }

SOLUTION:

The codes which I received are pasted below for reference. This is done so that you dont have to wait for @admin to link solutions up :-). Please copy them and paste at a place where you are comfortable to read :).

Setter

View Content

Tester

View Content

Editorialist's solution will be put on demand. :)

$Time$ $Complexity-O(NlogN)$

CHEF VIJJU'S CORNER:

1. Ans Q1-Why $R_i$ in descending order? Simple, because if $L_i$ are same, then inserting larger segment first helps us to easily find if $k$ segments intersect.

View Content

2. Ans Q2-I quote "we need not make a custom data type, merely storing the end points of lines can do." (Why?Q2)

View Content

3. Ans Q3-Now, either the multiset is empty, or we have number of lines which intersect with given $i'th$ line.

View Content

4. You can find inverse-factorial in $O(N)$ time. Refer here or at tester's code.

5. What lies in here?

View Content

6. Test Case Bank

View Content

7. Related Problems-

MINIONS - Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Igor Barenblat
Tester-Misha Chorniy
Editorialist-Abhishek Pandey

DIFFICULTY:

Medium

PRE-REQUISITES:

Segment Tree

PROBLEM:

Given $N$ pairs of integers, find a $sub-set$ of maximum size such that $min(a_1,a_2,...,a_k) \ge$ $\large \frac{b_1+b_2+..+b_k}{k}$

QUICK EXPLANATION:

Key to Success- A good grasp over segment tree, implementing it properly and/or good debugging skills can help you get an AC. Implementation practice is a must.

We make $2$ arrays of pairs. The first one, $Arr[]$ will store the pair $\{a_i,b_i\}$ and second one $index[]$ will store $\{b_i,i\}$ (where $i$ is the index). We now sort both these arrays. Starting from end of $Arr[]$ (i.e. from the pair with maximum $A_i$ to pair with minimum $A_i$ [helps avoiding finding the minimum $A_i$ every time] ) we try to find maximum number of $\sum_{i=1}^{i=k}b_i$ such that $k*A_i \ge \sum_{i=1}^{i=k}b_i$ which can be done using segment tree.

EXPLANATION:

This editorial is divided into $2-3$ sections. The first section will describe the concept and thinking process to solve the question. The second one will brief about implementation as I find it tricky solution. We will refer to tester @mgch solution for that.

The concept involved will discuss-

  • What to store in segment tree?
  • How will we store and why it works?
  • Query and Updates. Implementation is integrated with this section.

1.What to store in segment tree-

I acknowledge that we can approach this problem in many ways. We will discuss tester's approach here.

He decided to store $2$ things- $\sum_{i=l}^{i=r}b_i$ in that range, and $r-l+1$ (i.e. sum of $b_i$ and number of elements in the given range). Instead of storing them in a single node, he made $2$ arrays for that. Please dont get confused by that :)

2.How we will store and why it works-

We made $2$ arrays $Arr[]$ and $Index[]$. We will store sorted $\sum_{i=l}^{i=r}b_i$ in the nodes. What does this mean and why does it work?

Lets first discuss the proof that its correct and then discuss further working.

DING!!
DING!!
DING!!

Oh no! You hear that alarm? It means its time for some hand exercises! Grab your pen and paper and lets get to it :).

Q- Given a sorted array $C[]$ such that $C_1 \le C_2 \le C_3 \le ... \le C_k$, prove that $C_1$ $\large \le \frac{(C_1+C_2)}{2} \le \frac{(C_1+C_2+C_3)}{3}...$.

I think the standard mathematics proof is simple. Let me give an intuitional proof! Its given in tab below so that it doesnt give spoilers to those who want to give a try!

View Content

The tester's proof will be given in Chef Vijju's corner.

Now, keeping the ahead proof in mind, and our objective to find the maximum size of set, we will query for maximum $k$ such that $\sum_{j=1}^{j=k}b_j +B_i \le (k+1)*A_i$. Here $\sum_{j=1}^{j=k}b_j $ are already in the tree, and we are querying for pair $\{A_i,B_i\}$

Why $(k+1)*A_i?$ Where did the division go? What is this $A_i?$ How is this minimum?

View Content

The required query is standard. But wait! How do we guarantee that the $B_i$ chosen are only from the pairs such that their $A_i$ are greater than or equal to the current $A_i$ we are using this as minimum? This will be discussed in next section, where we will complete whats exactly stored in the tree and how/why it works. Make sure that the question/proof given to you above is clear!

3. Query and Update-

Now, you guys would be at least a little confused. Things were going smooothly but then this evil editorialist threw up an evil question on your face :(

Well, turns out its simple to fix as well!

Instead of building tree at once, we build it step by step. What we do, is, that the tree is initially empty.

As we iterative from pairs with maximum $A_i$ to minimum $A_i$, we add the $B_i$ to the tree by updating the tree.

View Content

Reference code is below-

//For all i from n-1 to 0 (we sorted the pairs already!)
//Do query
//Now we have to update. See code below.
int where = lower_bound(idx.begin(), idx.end(), make_pair(f[i].second, i)) - idx.begin();//Find required position. idx=index array
upd(where, +f[i].second);

upd function is given below-

void upd(int r, int val) {
    r += sz;//From leaf
    t[r] += val;//t stores sum of Bi
    c[r] += 1;//Stores number of elements in range
    while (r > 1) {
        t[r >> 1] = t[r] + t[r ^ 1];//Parent child=Stats of Left Child+Stats of Right Child
        c[r >> 1] = c[r] + c[r ^ 1];
        r >>= 1;
    }
}

The query function is also easy. The tester used iterative segment tree. The query function (along with update) is given below-

    for (int i = n - 1; i >= 0; --i) {//For all pairs from n-1 to 0
        if (f[i].first >= f[i].second) {
            ans = max(ans, 1);//Ans at least 1 if Ai>=Bi
        }
        long long cur = f[i].second;
        int now = 1, root = 1;//Root is 1. 
        while (root < sz) {//sz=size of tree
            //Even child (2n) has lesser sum than (2n+1) child.
            if ((t[root] + cur) <= 1LL * (c[root] + now) * f[i].first) {
                now += c[root];//Now= current Ans
                ans = max(ans, now);
                break;
            }
            root <<= 1;//Check the child
            if ((t[root] + cur) <= 1LL * (c[root] + now) * f[i].first) {
                now += c[root];
                cur += t[root];//Curr=Sum Bi till now
                ans = max(ans, now);
                root |= 1;//equivalent to root+=1. Done to check odd child in next iteration
            }
        }
            //After querying, add the Bi to the tree.
        int where = lower_bound(idx.begin(), idx.end(), make_pair(f[i].second, i)) - idx.begin();
        upd(where, +f[i].second);

Now your turn! Refer to tester's code. Right now, you might feel its easy to do. Try writing your own recursive version of the code! You will face a few (or many) WA, dont worry. Debug them, that will give you tremendous improvement. Refer to editorial, ask doubts! Dont get disheartened by WAs :). Debugging segment tree sometimes give headaches even to red coders, so practice the proper implementation by writing the recusrive solution!

SOLUTION:

The codes which I received are pasted below for reference. This is done so that you dont have to wait for @admin to link solutions up. Please copy them and paste at a place where you are comfortable to read :).

Setter

View Content

Tester

View Content

Editorialist's solution will be put on demand.

$Time$ $complexity=$ $O(NlogN)$

CHEF VIJJU'S CORNER:

1. I mentioned a line in the comments of query function. //Even child (2n) has lesser sum than (2n+1) child.. Prove this. Hint in tab below. (You may assume same number of terms in both nodes)

View Content

2.Tester's Notes-

View Content

3. Tester's Proof-

View Content

4. Read tester's notes. He said something about "Tree must have ${2}^{l}$ leaves" for his iterative version to work. Why?

5. Refer to tester's solution. Try to write a recursive solution to the same. :)

6. Test Case Bank-

View Content

7. OMG YOU READ TILL HERE? Here, I have an awesome blog on segment trees for you :) . Click here

8. Related Problems-

  • Set of Questions
  • One question from Hackerearth. Check out their section for more! Refer to my previous segment tree editorials as well for more :)

Getting TLE

$
0
0

link of problem-->> https://www.hackerearth.com/practice/algorithms/greedy/basics-of-greedy-algorithms/practice-problems/algorithm/swap-it-2/ link of my solution-->> https://www.hackerearth.com/submission/17626488/ my logic-->>We first pick the smallest element from array a1, a2, a3…(ak or an) [We consider ak when k is smaller, else n]. We place the smallest element to the a0 position after shifting all these elements by 1 position right. We subtract number of swaps (number of swaps is number of shifts minus 1) from k. If still we are left with k > 0 then we apply the same procedure from the very next starting position i.e., a2, a3,…(ak or an) and then place it to the a1 position. So we keep applying the same process until k becomes 0.

please someone help and thanks in advance.

cant get whats wrong in my code

Invitation to CodeChef June Cook-Off 2018 sponsored by ShareChat!

$
0
0

Hello CodeChef Community!

We’re happy to present to you another fresh set of challenges for your coding skills with the June Cook-Off 2018 sponsored by ShareChat. In addition, there are some exciting job/internship opportunities by ShareChat in the June Cook-Off 2018. More details on the June Cook-Off contest page here: COOK95 Looking forward to seeing your participation in yet another exciting monthly contest! Joining me this time on the problem setting panel are:

  • Problem Setter: barenuz (Igor Barenblat)
  • Problem Tester: mgch (Misha Chorniy)
  • Admin: kingofnumbers (Hasan Jaddouh)
  • Problem Editorialist: vijju123 (Abhishek Pandey)
  • Statement Verifier: xellos0 (Jakub Safin)
  • Russian Translator: xcwgf666 (Sergey Kulik)
  • Mandarin Translator: huzecong (Hu Zecong)
  • Vietnamese Translator: (VNOI Team)

Contest Details:

Time: 17th June 2018 (2130 hrs) to 18th June 2018 (0000 hrs). (Indian Standard Time — +5:30 GMT) — Check your timezone.

Contest link:https://www.codechef.com/COOK95

Registration: You just need to have a CodeChef handle to participate. For all those, who are interested and do not have a CodeChef handle, are requested to register in order to participate.

Prizes: Top 10 performers in Global and Indian category will get CodeChef laddus, with which the winners can claim cool CodeChef goodies. Know more here: https://discuss.codechef.com/questions/51999/how-do-i-win-a-codechef-goodie. (For those who have not yet got their previous winning, please send an email to winners@codechef.com)

Good Luck!
Hope to see you participating! Happy Programming!

Testing solutions for correctness

$
0
0

Dear Community,

Since the past few months, I have been struggling with submitting correct solutions to problems. Most of the times I am able to devise an algorithm, write code and also pass the sample cases provided. Also i design edge cases as much as possible and try to pass them. Unfortunately, it has become a pattern where I fail some test case that I can't find.

Can you please help with how you test solutions? Some of the questions I have no idea why they failed -

CHEFPTNT

MULTHREE

Thanks a lot,

Ruddra


FLIPCOIN - the definite topic for us to learn Segtrees!!

$
0
0

I know it can be solved using Binary Indexed Trees. I read them, but still haven't been able to find a solution. Can someone explains me the algo, please.... :)

MULTHREE - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Sidhant Bansal
Testers:Hasan Jaddouh
Editorialist:Sidhant Bansal

DIFFICULTY:

easy

PREREQUISITES:

modulo cycle, basic math

PROBLEM:

The key idea behind the solution is the fact that the digits start to repeat after some time in a cycle of length 4. Firstly, we will find the sum of all the digits and then check if it is divisible by 3 or NOT.

Sum of digits -

We know $d_{0}$ and $d_{1}$. So what will be $d_{2}, d_{3}, ...$ ?

$d_{2} = (d_{0} + d_{1})\mod 10$

$d_{3} = (d_{2} + d_{1} + d_{0}) \mod 10 = ((d_{0} + d_{1}) \mod 10 + d_{0} + d_{1}) \mod 10 = 2 * (d_{0} + d_{1}) \mod 10$

$d_{4} = (d_{3} + d_{2} + d_{1} + d{0}) \mod 10 = 4 * (d_{0} + d_{1}) \mod 10$

$d_{5} = (d_{4} + d_{3} + d_{2} + d_{1} + d_{0}) \mod 10 = 8 * (d_{0} + d_{1}) \mod 10$

$d_{6} = (d_{5} + ... + d_{1} + d_{0}) \mod 10 = 16 * (d_{0} + d_{1}) \mod 10 = 6 * (d_{0} + d_{1}) \mod 10$

$d_{7} = (d_{6} + ... + d_{1} + d_{0}) \mod10 = 12 * (d_{0} + d_{1}) \mod 10 = 2 * (d_{0} + d_{1}) \mod 10$

If we keep on making $d_{i}$ we will see that the resultant is just looping through the same values. Rigorously, we can see that $d_{0}$ contributes $1$ time(s) to $d_{2}$, $2$ times to $d_{3}$, $4$ times to $d_{4}$, $8$ times to $d_{5}$, ..., $2^{k - 2}$ times to $d_{k}$. But since the powers of $2$ under modulo $10$ cycle from $1$, $2$, $4$, $8$, $6$, $2$, $4$, ... Similarly for $d_{1}$.

Here the cycle length is of 4, where $d_{2}$ is not present in the cycle. Let $S = (2*(d_{0} + d_{1})) \mod 10 + (4*(d_{0} + d_{1})) \mod 10 + (8*(d_{0} + d_{1})) \mod 10 + (6*(d_{0} + d_{1})) \mod 10$

So the sum of digits = $d_{0} + d_{1} + d_{2} + S * ((k - 3) / 4) + x$, here the first 3 terms will be covered by $d_{0}, d_{1}, d_{2}$ and after that the groups of 4 will be covered by S, but this formula will still have not have summed some terms at the end left when $(k - 3)$ is not divisible by $4$ (the sum of these terms is denoted by $x$ and the explanation regarding them is given using the example shown below)

Example $\rightarrow$ $k = 13$, The sum of digits = $d_{0} + d_{1} + d_{2} + S * 2 + x$Then it will have $d_{0}, d_{1}, d_{2}$ then the first $S$ will have $d_{3}, d_{4}, d_{5}, d_{6}$ and the second $S$ will have $d_{7}, d_{8}, d_{9}, d_{10}$. Now the remaining terms, i.e $d_{11}$ and $d_{12}$ still needs to be added which is being referred to as $x$ in the above formula. For this we can simply say that

$d_{11} = 2*(d_{0} + d_{1}) \mod 10$

$d_{12} = 4*(d_{0} + d_{1}) \mod 10$

And $x = d_{11} + d_{12}$

Time and space complexity of this solution is $O(1)$.

For implementation details please refer to the solutions attached below.

SOLUTIONS

Setter's solution.
Tester's solution.

GOODPERM -Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Igor Barenblat
Tester-Misha Chorniy
Editorialist-Abhishek Pandey

DIFFICULTY:

Simple

PRE-REQUISITES:

STL, Generate all Permutations of an Array

PROBLEM:

Given a partially filled permutation $p$, we have to find number of possible good permutations from it. A permutation is good if-

  • It has all numbers from $[1,n]$
  • Number of positions such that $p_i>p_{i-1}$ is exactly equal to $K$

QUICK EXPLANATION:

Key to Success- Anyone with good knowledge of STL and implementation skills can do this question very, very easily!

We generate all permutations of $[1,n]$ and check if-

  • it satisfies the condition of number of $p_i>p_{i-1}$ equal to $K$.
  • it can be achieved from sequence $A$

We can easily use C++ STL's $next$_$permutation()$ to generate the permutations easily.

EXPLANATION:

This editorial will have a single section. There is little concept to be discussed, hence we will discuss the cleanest way of implementing it quickly. We will refer to Setter's solution for it :)

Setter's Solution-

"I took the input Mr. Editorialist. WTF THIS QUESTION SO DIPHICULT I CANT SOLVE WTFWTF?!"

Hold your breath young man/woman/boy/girl/whatever. We shall deal with the question one step at a time, i.e. @step_by_step .

The first thing will be, to make a new array for permutations. Remember, that repetitions are not allowed in permutations, and all numbers in range $[1,n]$ must occur exactly once!!

Since we plan to use $next$_$permutation()$ function from STL, lets generate the lexicographically smallest permutation first. In other words, initialize new permutation array $p[]$ as- $p[]=\{1,2,3,...,n\}$. Code for it-

for (int i=1;i<=n;i++){ p[i]=i; }

Our $next$_$permutation()$ will generate ALL permutations for us. We only have to check $2$ things-

  • If that permutation is achievable from $a$
  • It satisfies the condition of number of $p_i>p_{i-1}$ equal to $K$.

When will a permutation be achievable from $a$? Recall that, we can only fill in $0's$, and not shuffle permutation $a$. Hence, we can say that a permutation is valid IF AND ONLY IF-

  • $A_i==0$ and $P_i$ doesnt occur elsewhere in $A_i$.
  • $A_i \neq 0$ and $P_i==A_i$.

In other words, if $A_i$ is $0$ and the element $P_i$ can be inserted in $A$, or if $A_i \neq 0$, then $P_i$ must be equal to $A_i$, because shuffling/moving-elements is not allowed.

A sample code for that is-

`for (int i=1;i<=n;i++){
            if (a[i]>0 && a[i]!=p[i]){
                //Invalid Permutation
            }
        }`

Note that we didnt check for "$A_i==0$ and $P_i$ doesnt occur elsewhere in $A_i$." It is redundant. Why? (Q1)

Now what is left is, simply, to check the count of $P_i>P_{i-1}$ being equal to $K$. Simple looping for that is needed. A sample code-

for (int i=2;i<=n;i++){ if (p[i]>p[i-1]){ cnt++; } }

A full overview of working loop is given in tab below-

View Content

Thats it! We're done with this question now as well :)

SOLUTION:

The setter and tester's code are pasted in tabs below because @admin can take some time in linking the solutions. Please refer to them :)

Setter

View Content

Tester

View Content

Editorialist Solution will be put on demand

$Time$ $Complexity=O(N!*N)$ (Setter)
$Time$ $Complexity=O(???)$ (Tester)

CHEF VIJJU'S CORNER :D

1. Note that we didnt check for "$A_i==0$ and $P_i$ doesnt occur elsewhere in $A_i$." It is redundant. Why?

View Content

2. Tester's Solution- He solved it using $dp+bitmask$, which should deserve a mention here :).

View Content

3. Refer to Tester's code and his notes. Derive the time complexity of his solution in worst case.

View Content

4. Test Case Bank-

View Content

5. Related Problems-

Virtual-Online-Competitive-Judge (Script)

$
0
0

Virtual Online Judge generates a random set of questions from various Online Websites for competitive programming such as Codechef, Codeforces etc. It creates a contest containing five problems sorted by difficulty and a user may submit solutions to these problems in any order. Questions from these websites are scraped and can be viewed by the user on a basic GUI created on python using Tkinter.

Every competitive programmer wants a good mix of questions from different judges and to have a script which would create a completely random contest any number of times would be a delight for a competitive programmer.

Click 'here' to view the Github repository.

Help in Polynomial Multiplication

help in codeforces problem 580/C (Kefa and park).

delay in editorials

$
0
0

Why does codechef take too much time in posting editorials? They should be posted just after the end of contest like in codeforces so that we can find mistake in our approach.


Tutorial - Beginner and Advanced.

Call for Setting Hard Problems At CodeChef

$
0
0

Hi fellow coders,

Here at CodeChef, we believe you’re a great problem setter and would be delighted to have you on our problem setting team. For the upcoming long contests, we are in need of more problems with a higher difficulty level, we hope to find hard problems with non-trivial ideas.. If you have some problems of that level, that would be great:) Even otherwise, you can always send your ideas.

Please see the links below to understand our problem setting guidelines and to see the submission form.

We look forward to seeing you setting amazing problems on CodeChef! It would be great to work with you :)

Thanks a lot in advance!
Regards,
Misha Chorniy (mgch)

A Learning Module for Beginners (Currently in Development, Feedback requested)

$
0
0

Hi fellow programmers,

We are planning to create a course for beginners. Beginners often come to the site and got overwhelmed by so many problems present on the site. Many of them often ask where to start from. So, we thought of creating a course module for them. The module will be a set of tutorials and a set of practice contests on CodeChef.

For this module, we will identify the key set of topics that a beginner should solve in order to reach a certain level. For each topic, we will have some 5 to 10 or more problems on that topic that she should solve. I have collected some set of problems for following topics (in increasing order of the difficulty). Please feel free to give any relevant feedback, suggest some problems that you think can be added or removed. Any suggestions regarding would be most welcome.

Note that currently, this module is not ready. It's still work in progress. I have marked this post a community wiki. Please feel free to edit it.

Module #0: What's competitive programming?

Competitive Programming is a mind sport where participants solve problems by writing code. The problems in question are typically logical, mathematical or algorithmic in nature. Participants must write code according to given specifications which typically includes a pre-specified time and memory limits within which a program must successfully complete execution.

Two of the most prominent competitive programming competitions are the ACM International Collegiate Programming Competition (ICPC) and the International Olympiad of Informatics (IOI) which are for univeristy and high school students respectively. The ICPC is one of the oldest, largest, hardest and most prestigious programming competitions in the world, and it is widely considered as the "Olympics" of programming.

Some other prominent programming competitons are

  • Google Code Jam
  • Facebook Hackercup
  • Topcoder Open (TCO) Algorithm
  • Yandex Algorithm

Apart from the above, regular programming competitions are conducted on various platforms across the intetnet. Some of these are

  • Codechef
  • Codeforces
  • Hackerrank
  • Topcoder
  • Hackerearth
  • Atcoder
  • CSAcademy

Getting started with CodeChef platform

Module #1: Learning A Programming Language

Check https://www.codechef.com/ioi/basics, the section "Language Constructs - C++ - 1" for basic knowledge of C++. If you want to learn basics of other languages like Java, Python, you can refer to (need to provide more links).

Just get it done :) Starting questions to do

  • FLOW001 (add two numbers)
  • FLOW002 (find reminder of a number when divided by other number)
  • TEST (one of the starting problem to solve on CodeChef)
  • INTEST (for testing whether your input/output routines are fast enough)

Basic knowledge of if/else conditions

  • FLOW010 (basic knowledge of if/else conditions)
  • FLOW014 (another if/else knowledge question)
  • LADDU (very nice implementation problem to solve)

Dealing with numbers

  • FLOW002 (find remainder of a number a % b)
  • FLOW004 (find sum of first and last digit of a number)
  • FLOW006 (find sum of digits of a number)
  • FLOW007 (given a number, reverse it)
  • FCTRL (an interesting question, must solve)

Basic knowledge of arrays

Working with strings

  • NITIKA (reading strings, and string related formatting)
  • GOODBAD (ASCII characters, lower-case and uppercase characters)
  • FLOW015 (checks basic knowledge of strings and calendar)
  • FRGTNLNG (very nice question to test input processing skills)
  • LAPIN (check whether a string is a palindrome or not)
  • CSUB (good for understanding notion of substrings)

Handling floating point numbers

Off to recursion

Provide Few More Implementation Problems:

Space and time complexity of a program

Module #2: (Basic Mathematics)

Please see https://www.codechef.com/ioi/basics, Mathematics section for very basic mathematics.

Basic Number Theory:

Module #3: Sorting algorithms

Module #4: Greedy Algorithms

Module #5: Stacks and Queues

Stack:

Queue:

  • CHFQUEUE (very nice stack and queue related problem, must do)
  • COOK82C (easy-med level problem)

Module #6: Binary Search:

Module #7: Basic Dynamic Programming

  • ALTARAY (basic dp problem)
  • SUMTRI (very nice and basic dp problem)
  • DBOY (very nice dp problem, must do)
  • XORSUB (basic 2-D dp)
  • STRMRG (a variation of standard LCS (longest common subsequence) problem, must do problem)
  • GRID (simple 2-D dp, prefix/suffix sums over a 2-D matrix, must do)
  • STRSUB (dp with binary search)

Module #8: Basic Graph Theory

Depth first search

  • FROGV (can also be done without requiring dfs by making some simple observations, in fact, dfs is overkill for it)
  • FIRESC (must do dfs problem, can also be done using union-find algorithm)
  • CHFNFRN (check whether a graph is bipartite)
  • FRIEMEET
  • DIVIDE (binary search with bipartite checking type logic)
  • MCO16104 (consider the inverse graph)
  • AUEC (existence of euler circuit in a graph)

Breadth first search

Union Find

  • BIGOF01 (very basic problem on union find, must do)
  • COLGQU (slight harder version on union find)
  • DISHOWN
  • CHFNFRN (check whether a graph is bipartite)
  • MTRWY (slight harder version on union find)
  • JABO
  • FILLMTR (very nice problem on union find, intermediate level, you may also check the video tutorials)
  • GALACTIK (a very nice union find problem)
  • PARITREE (intermediate level problem)
  • SETELE (much recommended problem)
  • MAGICSTR (recommended only for intermediate+ level)

Advanced features of languages

Check Language Constructs. It's good to learn Standard Template Library (STL) - C++ 2 section in https://www.codechef.com/ioi/basics for reading.

100% attendance laddus

$
0
0

Has anyone received the laddus for 100% participation between March '17-Feb '18?

somebody pls explain the gennady approach masha and minions

Viewing all 39796 articles
Browse latest View live


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