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

New blog for Competitive Programmers

$
0
0

Hey guys I have started a new blog. The first article is on dfs lowlinks . You can read it up here. Feel free to comment if anything is wrong or suggest any changes you want me to make. Also feel free to suggest topics you want me to write some article on . Thanks. :D


recurrence relation with offset techinique

$
0
0

A recurrence relation of this type: $F_n = 2F_{n - 1} + 3F_{n - 2} + 3$ , where sum of the coefficient of recurring terms on both side of the equation is not equal.

I have seen a codechef video ( by Kevin ) where they explain the offset adding to solve this type of recurrence by removal of the constant term. The recurrence can be converted to $G_n = 2G_{n-1} + 3G_{n-2}$ and later use matrix exponentiation to solve it with matrix $\begin{bmatrix} 2&3\\ 1&0\\ \end{bmatrix}$ to obtain the value of $G_n \textit{ mod }M$. For example,

$\begin{align*} &\text{Let, }F_n = G_n + C\\ &\Rightarrow G_n + C = 2\left [ G_{n - 1} + C \right ] + 3\left [ G_{n - 2} + C \right ] + 3 \\ &\Rightarrow G_n + C = 2G_{n - 1} + 3G_{n - 2} + 5C + 3 \\ &\Rightarrow G_n= 2G_{n - 1} + 3G_{n - 2} + 4C + 3 \\ &\Rightarrow C = -\frac{3}{4} \\ \end{align*}$

Now after calculating the value of $G_n \textit{ mod }M$ how to recover $F_n$?

Thanks!

TSORT : Getting Wrong answer

$
0
0

Below is my code for TSORT. I checked it multiple times and looks good, but still I get "wrong answer". Please help!!

=====

include <stdio.h>

int main(void) { unsigned int array[1000001] = {0}; unsigned int t; unsigned int value = 0; char temp=0;

scanf("%d",&t);

while(t) {
    scanf("%d",&value);
    array[value] = array[value] + 1;
    t--;
}
t = 0;

while(t<=1000000) {
    if(array[t] >= 1) {
        for(temp=1; temp<=array[t]; temp++) {
            printf("%d\n",t);
        }
    }
    t++;
}
return 0;

}

Codeforces contest colliding with Codechef contest.

$
0
0

On 23rd june codeforces round is colliding with a rated contest in codechef. On 30th june again another codeforces contest is colliding with codechef lunchtime. Is it possible that the timings might be slightly changed that they don't collide? I'm sure many participants would like to give both contests and don't want to choose between the 2 especially since it is summer vacation and everybody has lot of free time.

All panlindromic subsequence.

$
0
0

here is a pseudo code for counting all palindromic subsequence of a given string :

enter code here
if i == j
return 1

Else if (str[i] == str[j)]
return   countPS(i+1, j) + countPS(i, j-1) + 1;

else
return countPS(i+1, j) + countPS(i, j-1) - countPS(i+1, j-1)

i couldn't understand that , when first and last characters are equal why we do not subtract -countPS(i+1, j-1)

as we did when when 1st and last are not same. ?

source : https://www.geeksforgeeks.org/count-palindromic-subsequence-given-string/

Can anyone please explain it ?

Regarding the new rating division system

$
0
0

The March Challenge 2018 witnessed two parallel contests for the two rating divisions for the first time ever in Codechef. However, there are a few issues regarding it which I want to discuss.

Codechef clearly states that the problems in the other division can be practiced and are “NOT part of the contest”.

I had planned to skip this March Challenge as our college fest was going on. However, I tried those div 2 problems in practice and boom, my name appeared on the ranklist with score ‘0’! Now this really needs to be fixed… @admin

The second and the last issue is undoubtedly a petty issue. The div 2 problems once solved, shows a yellow tick even if it is fully solved. Even the profile shows the problems in the partially solved section. I don't know the reason behind this.

However, overall, I am satisfied with this division system and it does motivate all the coders to strive hard for that green tick.

what is wrong ?

getting right output but codeChef showing wrong answer.

$
0
0

`#include <stdio.h>

include <math.h>

int main(void){ int t, a=0, b=0, n=0, r; scanf("%d",&t); while(t--){ scanf("%d %d %d",&a,&b,&n); a=pow(a,n); b=pow(b,n); if(a>b) r=1; else if(a<b) r=2; else if(a==b) r=0; printf("%d",r); } }`


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 :)

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-

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-

DANYANUM - Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Igor Barenblat
Tester-Misha Chorniy
Editorialist-?????

DIFFICULTY:

MEDIUM-HARD

PRE-REQUISITES:

SOS Dp, Square Root Decomposition, Bitwise Operations

PROBLEM:

Given an array $A$ of $N$ numbers, we have to support the following operations-

  • Add a number to it
  • Remove a number from it
  • Calculate $f(x)$ where $f(x)$ is the maximum of "Bitwise-AND" of all sub-sequences of $A$ with length $x$

QUICK EXPLANATION:

Key to Success- Deducing the type of question is important. The one who deduced that it is $SOS-DP$ and were able to derive that queries were to be broken by $Square-Root$ $Decomposition$ can get a AC. Such intuition comes with practice as questions on similar concepts are asked before.

Some experience of SOS Dynamic Programming helps here. We will use square-root decomposition along with it. Divide the queries into buckets of size $K$. Updates of frequency of elements and re-calculation of SOS dp-table takes place for every bucket instead of every query.

We will iterate over bits of answers from highest to lowest. Greedy works here! (Why? Q1). For each bit, we first set it and see if its possible obtain this answer. If it is, we set that bit of answe and move on to next.

EXPLANATION:

I will assume that you guys have at least some idea about SOS-Dp. The editorial will have a three sections, each describing one step towards the final answer. I will try to give my intuition and help in grasping concept wherever possible, but please make sure you fulfill the pre-requisites! Implementation is integrated with these sections- we use tester's code for that.

1.SOS-Dp

The first question to ask "What is the maximum AND we can obtain if we AND $a\&b$ where $a< b$? Of course, the answer will be $a$! Why? Is the maximum value obtainable from AND operation of $2$ numbers is the minimum one of them?

View Content

The function to calculate SOS dp table, along with explanation is below.

void SOS() { // sum-over-subsets
        memcpy(foo, cnt, sizeof(foo));//Initialized with cnt or frequency array of elements
        for (int bit = 0; bit < k; ++bit) {//Iterating from bit 0 to bit k (0-based index)
            for (int mask = 0; mask < 1 << k; ++mask) {
                if (~mask & (1 << bit)) {//If mask has '0' at that position
                    foo[mask] += foo[mask ^ (1 << bit)];
                              //Number of ways to get mask+=Number of ways to get supermask   
                } 
            }
        }
    }

Initially the dp-table is initialized with frequency array which has count of all the numbers till present query. Using the SOS-dp, we iterate from bit $0$ to bit $k-1$ $(0-based$ $indexing!)$. Now, what are ways we can obtain the given mask? Note that, no new bit is set in AND operation. A bit with value $0$ remains $0$, and bit with value $1$ can get reduced to $0$ or may remain $1$. Hence, the given mask can only be obtained by $super-masks$ (or numbers which have $1$ at ALL places where mask has, and may have $1's$ at other places where our mask has $0$.)

Hence, if mask has $0$ at current position, we add number of ways to obtain $super-mask$ (or $dp[super-mask]$) to $dp[mask]$. The proof of correctness of this procedure is given in the pre-requisites blog I gave link to. (Well, its standard SOS dp procedure, so hopefully it should be clear :) )

2. Square Root Decomposition of Queries-

Clearly, updating the SOS-Dp table is very costly! We cannot do that for every query. What we, hence do is, divide the queries into "buckets" or groups, each of size $K$. SOS dp table is calculated after every bucket (instead of after every query). Tester @mgch chosed this $K$ around $512$. Now, what does this mean? This means that, when we are at $K'th$ bucket, our SOS dp-table is updated till $K-1$ bucket, and we just need to do some manipulations so that we can use that data of SOS dp table, along with data of present bucket to solve queries. What are they?

3. Answering Queries-

First thing is, the $SOS$ dp-table is updated after end of every bucket, but the frequency array of elements can be updated every query as its simply $O(1)$. Frequency array is nothing but count of numbers/elements in the set. Sample code below in the tab-

View Content

We need frequency array to be up-to-date for solving queries of current bucket. Calculating answer after that is actually simple!

Now, for every query asking us to calculate $f(x)$, we first set answer as $0$. Then we start from the highest bit. We will see if its possible to set the bit or not. Recall that our SOS dp table $(dp[mask])$ stored the number of $super-masks$ which have $mask$ as a $sub-mask$. We have answers for $K-1$ bucket in $SOS-dp$ $table$, we have status of queries of present buckets as well stored. HOW can we obtain the final answer?

It will do justice for first giving the code and then explanation.

                if (t == 3) {
                int ans = 0;
                //constructing the answer from the highest bit to lowest one bit-by-bit
                //checking if we have 2^(k-1) in the answer,
                //
                for (int bit = k - 1; bit >= 0; --bit) {
                    int taked = ans | (1 << bit);//Checking if we can set this bit in 
                                    //ans
                    int cur = foo[taked]; //cur = the number of elements that has (ans | 
                                    //2^bit) as submask
                    //recalculating in O(2^K)
                    for (int j = i; (j & ((1 << K) - 1)) != 0; --j) {
                        if (T[j] == 1) {//T[j]=T at j'th query
                                                    //X[j]=X at j'th Query
                            if ((X[j] & taked) == taked) {
                             //Recall the maximum possible value of AND of 2 numbers. We are trying to 
                             //see if taked is a sub-mask of X[j]. 
                                ++cur;
                          //If above is true, and X was inserted==>Increase length of sub-sequence by 1.
                            }
                        }
                        if (T[j] == 2) {
                            if ((X[j] & taked) == taked) {
                                --cur;
                                //If above is true, and X[j] was removed, 
                                                            //the length of sub-sequence reduces by 1
                            }
                        }
                    }
                    if (cur >= x) { // checking if this number >= x then the answer for 
                                   //this query |= 2^bit
                        ans |= 1 << bit;//If possible, add 2^(bit-1) to ans
                    }
                    //Do we REALLY need to check sub-sequence of length==x?
                }

In above code, we first initialized answer to $0$. Now, we iterate from highest bit to lowest bit (greedily) and see if we can obtain $\ge X$ (Why not $==X?$ Q2) numbers such that $ans$ is their sub-mask. We have stats upto $K-1$ bucket in $SOS-dp-table$ (named $foo[mask]$ in above code). We now simply iterate and brute force over this present bucket. Depending on if a favourable number (number whose sub-mask is ans) was added or removed, we add or subtract $1$ from present sub-sequence length. Like this, every query is answered in $O(K)$ or $O(\sqrt{N})$ whatever you choosed :)

Try to answer the question I asked at end of code. //Do we REALLY need to check sub-sequence of length==x? :)

SOLUTIONS:

The codes of setter and tester are pasted below for your convenience- so that you can access them while @admin is linking the solutions to the editorial. It is, just for your convenience.

Setter

View Content

Tester

View Content

Editorialist solution will be put on demand.

$Time$ $Complexity=O(\sqrt{m}*{2}^{k}*k+m*sqrt{m}*k)$

CHEF VIJJU'S CORNER :D

1. Ans of Q1 "Why greedily setting bits works here?"

View Content

2. Ans of Q2- "Do we REALLY need to check sub-sequence of length==x?"

View Content

3. Setter's Note-

View Content

4. TEST CASE BANK-

View Content

5. Related Problems-

  • MONSTER - Based on SOS Dp + Square Root. Should practice this question as well :)

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-

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.

Viewing all 40121 articles
Browse latest View live


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