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

CHEFSOCK - Editorial

$
0
0

Problem Link:

Practice
Contest

Author:Misha Chorniy
Tester:Pushkar Mishra
Editorialist:Praveen Dhinwa

Difficulty:

Cakewalk

Pre-Requisites:

Implementation, Basic maths.

Problem Statement

Chef has money rupees with him. He spends jacketCost rupees for buying a jacket. He buys as many socks as he can by the money left after purchasing the jacket. Cost of a sock is given by sockCost. Each day, he uses two socks. He never cleans his socks after using them. You have to find whether there will be a day in which Chef will have one sock remaining.

Quick Explanation

We just have to check whether $\frac{(money - jacketCost)}{sockCost}$ is even or odd.

Explanation

Initial money that Chef have = $money$
We are guaranteed in the problem that $jacketCost \leq money$.
So the money left after buying a jacket (i.e. $money - jacketCost$) will be always non-negative.

Using the remaining money, Chef buys as many socks as we can, so he will buy $S$ socks where $S = \frac{(money - jacketCost)}{sockCost}$ where $/$ denotes an integer division. By integer division, we mean floor function (e.g. $\lfloor \frac{3}{2} \rfloor = 1$ and $\lfloor \frac{4}{2} \rfloor = 2$).

Now, we need to check if Chef wear two socks daily, will there be a day when he will have to wear a single sock? This is equivalent to checking $S$ is even or not.

For solving subtask 1, we can simply simulate the process of wearing two socks as follows:


int remS = S // remS denotes initial number of socks.
while (remS >= 2) {
  // wear two socks
  remS -= 2;
}
if (remS == 1) return "Unlucky Chef"
else return "Lucky Chef";

Time Complexity

$O(S)$ or $O(1)$ depending on the subtask.

Solution:

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

Please feel free to post comments if anything is not clear to you.


MSTEP - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Lalit Kundu
Tester:Kevin Atienza
Editorialists:Pushkar Mishra and Suhash Venkatesh

DIFFICULTY:

Cakewalk

PREREQUISITES:

None

PROBLEM:

Given is a grid of size $N \times N$. It contains numbers from 1 to $N^2$. You start at the cell numbered 1, move to 2, then to 3, and so on up till $N^2$. Report the total manhattan distance traversed in doing so.

EXPLANATION:

Subtask 1 and 2
We keep an array $M$ of size $N^2$ and a variable $Dist = 0$. $M[i]$ stores the coordinates of number $i$ in the grid. Let $M[i].x$ denote the $x$-coordinate and $M[i].y$ denote the $y$-coordinate. $Dist$ stores the total distance moved. Once array $M$ has been filled, we can iterate from $i\,=\,1$ to $N^2$ and keep increasing the variable $Dist$ by the distance moved while going from $i-1$ to $i$:

$Dist = Dist +$ $abs(\,M[i].x-M[i-1].x)\,\,$ $+$ $abs(\,M[i].y-M[i-1].y)\,\,$

Note that Manhattan distance between $i$ and $i-1$ is being added to $Dist$. This is because the question says that you can only move from one cell to another if the latter shares an edge with the former.

COMPLEXITY:

$\mathcal{O}(N^2)$

SAMPLE SOLUTIONS:

Author
Tester
Editorialist

Why Runtime error:bad_alloc

$
0
0
        int S;
    cin>>S;
    vector<float> v;
    float a=0.0;
    float d;
    while(S--){
        if(S>0)
        d=1/S;
        else d=1;
        for(a=0.0;a<=2.0;a+=d){
            v.push_back(a);
        }
    }

Getting bad_alloc i.e runtime error. Please any one?

need help to solve - hidden password (ACM 2003, abridged)

BITTWIST - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Constantine Sokol
Tester:Pavel Sheftelevich
Editorialist:Praveen Dhinwa

DIFFICULTY:

medium-hard

PREREQUISITES:

Sqrt decomposition

PROBLEM:

Let's define bitTwister(x, y) function using the following code snippet written in Python:

def bitTwister(x, y):
  x ^= x >> 11
  x ^= (x << 7) & 2636928640
  x ^= (x << 15) & 4022730752
  x ^= (x >> 18)
  return (1812433253 * (x ^ (x >> 30)) + y) & 4294967295

You are given a tree $T$ consisting of $n$ nodes.
Let's define children(v) as a sequence of the children of v placed in the increasing order of their ids. We define children(v, d) as following.

  • $children(v, 0) = [v]$
  • $children(v, 1) = children(v)$
  • $children(v, d) = children(children(v)[1], d - 1) + children(children(v)[2], d - 1) + ... + children(children(v)[|children(v)|], d - 1)$ if $d > 1$

Let's define $reducedByBitTwister(X_1, X_2, ..., X_k)$ as following: $reducedByBitTwister(X_1) = X_1$ $reducedByBitTwister(X_1, ..., X_{k - 1}, X_k) = bitTwister(reducedByBitTwister(X_1, ..., X_{k - 1}), X_k)$ if $k > 1$

Your are asked to process $Q$ queries of the following kind: given two integers v and d (1 ≤ v ≤ n), let's denote children(v, d) as a node sequence V1, V2, ..., Vk. Your should calculate $reducedByBitTwister(A_{V_1}, ..., A_{V_k})$. It's guaranteed, that $children(v, d)$ is a non-empty sequence for each query.

QUICK EXPLANATION:

For each of the queries, let's find $(l, r)$ - the leftmost and the rightmost children of $v$ on the $d$'th level. After that, let's calculate the answer in $\mathcal{O}(|\text{children of v on the d'th level}|)$ and memoize it - if we'll get the same pair $(l, r)$ later, we'll just return the value without calculating it again.

It can be shown, that such the sum of $\mathcal{O}(|\text{children of v on the }$d${'th level}|)$ all over the testcases is no more than $\mathcal{O}(n \, sqrt \, n)$.

The total complexity is $\mathcal{O}(q * log n + n * sqrt \, n)$.

EXPLANATION:

Detailed explanation of the proof of time complexity being $\mathcal{O}(n \, sqrt \, n)$ will be added later. Please have a look at tester's solution for a very clean implementation of the approach.

AUTHOR'S AND TESTER'S SOLUTIONS:

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

CHEARMY - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Prateek Gupta
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

Easy

PREREQUISITES:

finding pattern, base 5 representation, simple maths

PROBLEM:

A number $n$ is called a magical number if the sum of product of individual digits (in base 10 representation) of each subsequence of digits is even. You have to find $K$-th magical number.

QUICK EXPLANATION:

A number $n$ will be magical number, iff all of its digits are even. Represent $K$ in base 5, and the corresponding number with each digit $0 \leq i < 5$ being mapped to $2 * i$ will be the $K$-th magical number.

EXPLANATION:

Properties of a magical number
Lemma: A number will be magical number, if all of its digits in decimal representation are even.
Proof: You can observe this property by finding a pattern by writing a bruteforce solution for small numbers. A more formal proof follows.

Note that the order of digits of $n$ does not matter. Product of digits of subsequence containing only even digits will be even. Similarly, a subsequence containing any even digit will be even. Now, all the subsequences that remain are the ones which consist of all odd digits. Sum of each such subsequence will be odd. Number of such subsequences will be $2^o - 1$ where $o$ denotes number of odd digits in $n$. Note that $2^o - 1$ will be odd if $o$ is non-zero. Hence if a number contains even a single odd digit, sum of product of digits of subsequences will be odd.

Finding K-th number
Note that you can view magical numbers in decimal representation as numbers written in base 5 representation, where a digit $i$ in base 5 has the value of $2 * i$ (which will be an even number) in decimal, e.g. 2480 (decimal) can be thought 1240 (in base 5).

Finding $K$-th number in base 5, is same as representing $K - 1$ in base 5. You can find the corresponding magical number in decimal representation by replacing each digit $i$ by $2 * i$.

Example
Assume we have to find $K = 10$-th magical number.
Write $K - 1$ in base 5, $K - 1 = 9 = (14)*5$.
Now replace digit $i$, with $2 * i$, i.e. $(28)*{10}$.
Therefor, $10$-th magical number will be 28.

Time Complexity:

$\mathcal{O}(log_5^{K})$ - Represent $K$ in base 5.

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester

getting RE need help finding bug

DEVARRAY - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Praveen Dhinwa
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

Cakewalk

PREREQUISITES:

Basic maths, finding minimum and maximum of an array

PROBLEM:

You have an array of size $N$. Apply the following operation $N - 1$ times

  • Pick any two elements $x, y$ in the array and replace them with a number $z$ s.t. $min(x, y) \leq z \leq max(x, y)$.

Notice that after $N - 1$ such operations, the array will contain a single element, as each operation reduces the size of array by 1.

You have to answer many queries - each asking whether the final single element could be equal to some given number or not.

QUICK EXPLANATION:

The final element of the array could be any number between the minimum element and the maximum element of the array, both inclusive.

EXPLANATION:

Notice that final number can not be less than the minimum element of the array. Similarly it can not also be more than the maximum element of the array.

Lemma Any number between the minimum and the maximum element of the array, can be a possible final number.
Proof Let $z$ be any such element, such that $z$ lies between minimum and the maximum element of the array.
We can follow the below given strategy to always end up with $z$.
In the first operation, pick the minimum and the maximum element of array and replace them with $z$.
In the remaining $N - 2$ operations, we can pick $z$ and any other element $w$ in the array. We can always replace these two elements by $z$. If $w < z$, we can replace by $max(w, z) = z$, otherwise by $min(w, z) = z$.

So, for each query, we just have to just whether the given query element is between the minimum and maximum element in the array or not.

Note that in subtask 1, we can simply this solution even more. If array consists of all 1's, then the final element will be 1. Similarly is the case of 2. If the array consists of both 1 and 2, then we can obtain both 1 and 2. In other words, for each query, we just have to check whether that number is present in the array or not.

Time Complexity:

$\mathcal{O}(N)$ to find the minimum and maximum elements of the array.
$\mathcal{O}(Q)$ for answering the queries - $\mathcal{O}(1)$ for each query.
Total $\mathcal{O}(N + Q)$

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester


CHSQARR - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Vasya Antoniuk
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

medium

PREREQUISITES:

partial sums, dequeue, dynamic programming

PROBLEM:

You are given 2-D matrix $A[n][m]$. The matrix will be called good if there exists a sub-matrix (continuous rectangular block of matrix) of dimensions $a \times b$ whose all of its elements are equal. In a single operation, you can increase any element of the matrix by 1. Find out minimum number of operations required to make the matrix good.

QUICK EXPLANATION:

For finding sum of a sub-matrix, you can use partial sums.
For finding maximum element in a sub-matrix, your can use doubly ended queue or deque.

EXPLANATION:

Let us consider some $a \times b$ dimension sub-matrix. Let $x$ be the largest element in the sub-matrix. Let $S$ be the total sum of elements in the sub-matrix. For making all the elements equal in minimum number of operations, we should aim to make all the elements equal to $x$. So, the minimum number of operations required will be $x * n * m - S$.

So, we have to find the sum and maximum element in all the possible sub-matrices of dimension $a \times b$.

For finding sum of all sub-matrices of sizes $a \times b$, we can use maintain partial sum sub-matrix. For that, we maintain another array, $sum[n][m]$, where $sum[i][j]$ will denote the sum of elements of the sub-matrix with left top end coordinate being $(1, 1)$ and right bottom coordinate being $(i, j)$. After computing $sum$ matrix, we can find the sum of any sub-matrix.

Now let us learn about how to find maximum element in all sub-matrices of sizes $a \times b$. Let $maxCol[i][j]$ be the maximum element of the sub-matrix in the column starting at $(i, j - b + 1)$ and ending at $(i, j)$ (i.e. of column of length $b$).

Assume that we have computed $maxCol$ array efficiently, let us find how we can use this to calculate maximum of $a \times b$ sub-matrix.

Let $max[i][j]$ denote the maximum value of sub-matrix of $A$ ending at $(i, j)$ (bottom right point), and of dimensions $a \times b$. Note that $max[i][j]$ is maximum of $maxCol[i - a + 1][j], maxCol[i - a + 2][j], \dots, maxCol[i][j]$. Note that for calculating $max[i][j + 1]$ from $max[i][j]$, we have to add a new element $maxCol[i][j + 1]$ and remove the element $maxCol[i - a + 1][j]$.

That means, that we have to maintain maximum of a constant size subarray of an array, i.e. at each step, maintain maximum with inserting and deleting one element at each step. Note that we can compute $maxCol$ in similar way.

This can be done either maintaining a multi-set (balanced binary search tree) of $K$ elements, in which insertion/deletion and finding maximum can be done in $\mathcal{O}(log(n))$ time. Sadly this method is slower for passing largest subtask.

You can find a $\mathcal{O}(n)$ solution for it by using doubly ended queue (aka deque). Please see this link for its very detailed explanation.

Time Complexity:

$\mathcal{O}(n m)$ for finding both $maxCol$ and $max$ matrices.

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester

CHINSM - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Vlad Mosko
Tester:Hiroto Sekido
Editorialist:Kevin Atienza

DIFFICULTY:

Medium

PREREQUISITES:

Divisor lists, intervals, combinatorics, ad hoc

PROBLEM:

Given an array of integers $[A_1, \ldots, A_N]$ and a number $K$, find the number of subarrays containing no bad pairs. A pair $(i,j)$ is a bad pair if $i < j$ and $(A_i \bmod A_j) = K$.

QUICK EXPLANATION:

  • For each position $j$, compute the largest $i_j < j$ such that $(i_j,j)$ is a bad pair. Collect all such bad pairs gotten this way, sorted by $j$. (There are at most $N$ such pairs, but may be less, because for some $j$s there could be no such $i_j$s).
  • Remove a pair $(i_j,j)$ if $j > 1$ and $i_{j-1} \ge i_j$.
  • Add the pair $(N, N+1)$ at the end of the list.
  • Assume that the list of pairs acquired is $[(i_1,j_1), (i_2,j_2), \ldots, (i_m,j_m)]$. Then the answer is: $$\frac{N(N+1)}{2} - \sum_{n=1}^{m-1} i_n (j_{n+1} - j_n)$$

To compute all pairs $(i_j,j)$, we need to store, for each value $v > K$, the maximum $i < j$ such that $A_i > K$ and $(A_i \bmod v) = K$ (there are at most $\max A_i$ such lists). We also store the maximum $l < j$ such that $A_l = K$. As we increase $j$, we need update some of these lists: When going to a new value of $j$ we only need to update at most $O(\sqrt{\max A_j})$ lists.

EXPLANATION:

Let's first assume that we have all the bad pairs, and we want to compute the number of subarrays containing no bad pairs. This is just equal to the number of subarrays (which is $N(N+1)/2$), minus the number of subarrays containing at least one bad pair. We will compute the latter instead, and we'll call a subarray bad if it contains at leaset one bad pair.

First, notice that all ${N \choose 2}$ pairs can be bad pairs (for example, if $A_i = 1$ for all $i$ and $K = 0$). Therefore we can't even compute all the bad pairs, because that is too slow. However, notice that not all bad pairs are important. For example, if the pair $p_1$ completely contains the pair $p_2$, then any subarray containing $p_1$ also contains $p_2$. Thus, the pair $p_1$ is redundant, i.e. if we remove the pair $p_1$ from our list, then the set of bad subarrays stay the same.

Thus we can remove all bad pairs completely containing other bad pairs. Note that after doing so, no two bad pairs share the same left (or right) endpoint any more (otherwise one will contain the other). Since there are at most $N$ endpoints, this reduces the number of bad pairs we have to at most $N-1$, which is more manageable :)

This also shows that for a given endpoint $j$, there is only at most one important bad pair $(i,j)$ ending in $j$, and it's the one with the maximum $i$. Therefore, the first step is to compute the maximum $i$ for each $j$ such that $(i,j)$ is bad (ignoring the $j$s for which there are no such $i$).

Bad pairs ending in every position

Assuming $A_j > K$, $(A_i \bmod A_j) = K$ is equivalent to: $$\begin{align*} (A_i \bmod A_j) &= K \\\ A_i &\equiv K \pmod{A_j} \\\ A_j &| (A_i - K) \end{align*}$$ This means that $A_j$ is a divisor of $(A_i - K)$.

For every endpoint $j$, we need to compute the maximum $i$ such that $(i,j)$ is bad. Surely, there are no bad pairs such that $A_i < K$ or $A_j \le K$, because $(A_i \bmod A_j) < K$ in those cases.

Suppose that, for every value $v$, $K < v \le \max A_i$, we store the value $i_v$, which we define as the maximum $i_v < j$ such that $(A_{i_v} \bmod v) = K$. Note that $i_v$ is also dependent on $j$, so as we increase $j$, we will need to update some of the $i_v$s, but for now, assume we can do those updates. If so, the $i$ we are looking for is simply $i_{A_j}$ :)

Now for the updates. As we leave a particular value of $j$ and go to the next one ($j+1$), we need to update some of the $i_v$s, specifically for those $v$s having $(A_j \bmod v) = K$. As shown above, this is equivalent to $v$ being a divisor of $A_j - K$, so we only update for those $v$s that are divisors of the number $A_j - K$. This is good, because it has only at most $2\sqrt{A_j - K}$ such divisors :)

Unfortunately, the last statement is incorrect for the case $A_j = K$. If $A_j = K$, then $A_j - K = 0$. But every $v$ is a divisor of zero! In this case, updating all the lists may be too slow, so we need to do something else. This is simple; we can simply maintain a separate value $l$, which is the maximum $l < j$ such that $A_l = K$. $i_v$ is now modified to exclude those $i$s such that $A_i = K$, and for an endpoint $j$, the $i$ we are looking for is now $\max(i_{A_j}, l)$ :) Thus, we maintain the fast running time!

The total running time of this step is $O(N \sqrt{\max A_i})$.

After getting the bad pairs $(i_j,j)$ for every such $j$, we can simply remove those pairs for which $i_{j-1} \ge i_j$, because those pairs are not important. Now we have a list of bad pairs $[(i_1,j_1), (i_2,j_2), \ldots, (i_m,j_m)]$ satisfying the following: $$i_1 < i_2 < \cdots < i_m$$ $$j_1 < j_2 < \cdots < j_m$$

Subarrays containing bad pairs

We now want to compute the number of subarrays containing at least one bad pair.

Each such subarray contains a unique "rightmost" bad pair, so we can compute, for each $1 \le k \le m$, the number of subarrays whose rightmost bad pair is $(i_k,j_k)$. Let's denote this by $f(k)$. Then the number of subarrays containing at least one bad pair is: $$\sum_{k=1}^m f(k)$$

Let's first compute $f(m)$ (the last one). For a subarray $[i\ldots j]$ to contain $(i_m,j_m)$, it must be true that $1 \le i \le i_m$ and $j_m \le j \le N$. There are $i_m(N+1-j_m)$ such choices for such subarrays, therefore $f(m) = i_m(N+1-j_m)$.

Now, let's compute $f(k)$ for $1 \le k < m$. The subarray $[i\ldots j]$ should contain $(i_k,j_k)$, but we need to ensure that this is the rightmost bad pair, i.e. the subarray doesn't contain $(i_{k+1},j_{k+1})$. This means that $1 \le i \le i_k$ and $j_k \le j$. However, $j < j_{k+1}$ should be true, otherwise it will contain the pair $(i_{k+1},j_{k+1})$. Therefore, there are $i_k (j_{k+1} - j_k)$ choices for such subarrays, and thus we have $f(k) = i_k(j_{k+1} - j_k)$ :)

This step runs in $O(N)$ time :)

Here's an implementation in C++:

#include <stdio.h>
#include <algorithm>
using namespace std;
#define ll long long
#define LIM 100111

int I[LIM];

int main() {
    for (int j = 0; j < LIM; j++) I[j] = -1;

    int n, k;
    scanf("%d%d", &n, &k);

    ll total = n*(n+1LL) >> 1;
    int pi = 0, pj = 1;
    #define add_pair(ci,cj) do {\
        total += pi * (pj - (cj));\
        pi = ci;\
        pj = (cj);\
    } while (0)

    int l = 0;
    for (int j = 1; j <= n; j++) {
        int a;
        scanf("%d", &a);
        if (a == k) {
            l = j;
        } else if (a > k) {
            int i = max(I[a], l);
            if (pi < i) {
                add_pair(i, j);
            }

            a -= k;
            for (int v = 1; v * v <= a; v++) {
                if (a % v == 0) I[v] = I[a / v] = j;
            }
        }
    }

    add_pair(n, n+1);

    printf("%lld\n", total);
}

Some implementation details:

  • We added a sentinel leftmost bad pair $(0,1)$ to make the add_pair macro simpler.
  • There is also a sentinel rightmost bad pair $(N,N+1)$ so that $f(m)$ (the last pair) is not special :)
  • There is no array $A$ allocated; instead the individual values of $A$ are inputted and processed on the fly.

Time Complexity:

$O(N\sqrt{\max A_i})$

AUTHOR'S AND TESTER'S SOLUTIONS:

setter
tester

CHNWGM - Editorial

BINOP - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Dymtro Berezein
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

Easy

PREREQUISITES:

binary operations

PROBLEM:

Chef has a string $A$. He wants the string to convert into string $B$ by applying the following operations as many times as needed. In each operation, we choose two indices $i, j, i \neq j$.

$result = A_i \, op \, A_j$
$A_i = result \, op \, A_i$
$A_j = result \, op \, A_j$

$op$ operation could be bitwise AND, XOR or OR operation.

Find out minimum number of operations required or state if it is impossible.

QUICK EXPLANATION:

If $A = B$, then no operation is required. In fact, problem guarantees that $A \neq B$.
If $A$ consists of all 1's or all 0's, then you can't convert it to $B$, as $A$ won't change with the operations.

Let $cnt_0$ denote the number of indices where $A_i$ and $B_i$ differ and $A_i = 0$.
Let $cnt_1$ denote the number of indices where $A_i$ and $B_i$ differ and $A_i = 1$.
Then, answer will be $max(cnt_0, cnt_1)$.

EXPLANATION:

If $A = B$, then no operation is required. In fact, problem guarantees that $A \neq B$.
If $A$ consists of all 1's or all 0's, then you can't convert it to $B$, as $A$ won't change with the operations.

Understanding of operations
Let us try to understand what these operations do?

OR operation:
$result = A_i \, OR \, A_j$
$A_i = result \, OR \, A_i$
$A_j = result \, OR \, A_j$

Which is equivalent to
$result = A_i \, OR \, A_j$
$A_i = result$
$A_j = result$

i.e. either $A_i$ or $A_j$ is 1, you can make both of them equal to 1.

AND operation:
$result = A_i \, AND \, A_j$
$A_i = result \, AND \, A_i$
$A_j = result \, AND \, A_j$

Which is equivalent to
$result = A_i \, AND \, A_j$
$A_i = result$
$A_j = result$

i.e. either $A_i$ or $A_j$ is 0, you can make both of them equal to 0.

XOR operation
$result = A_i \, XOR \, A_j$
$A_i = result \, XOR \, A_i$
$A_j = result \, XOR \, A_j$

Which is equivalent to
$result = A_i \, XOR \, A_j$
$A_i = result \, XOR \, A_i = A_j$
$A_j = result \, XOR \, A_j = A_i$

i.e., you can swap any two elements $A_i, A_j$, note that this operation will be useful if one of them is 0 and other 1.

Take some example
Let us take some example.

0 0 0 1 1
1 1 1   0 0

Note that you can not make any operation only among first three zeros to make all of these ones. You can swap first 0 and fourth 1, using XOR operation. After that swap second 0 and fifth 1. Now you will end up with

1 1 0 0 0
1 1 1   0 0

Now, you can take first one and third zero, and replace third number by 1, by using OR operation. You will end up with

1 1 1 0 0
1 1 1   0 0

So, in total we required three operations.

Final solution
Let $cnt_0$ be number of indices $i$, where $A_i = 0$ and $B_i = 1$.
Let $cnt_1$ be number of indices $i$, where $A_i = 1$ and $B_i = 1$.

Let us think about the $cnt_0$ elements, where $A_i = 0$ and $B_i = 1$. We have to change all of these zeros into ones. Note that this will require at least $cnt_0$ operations.

Let us think about the $cnt_1$ elements, where $A_i = 1$ and $B_i = 0$. We have to change all of these ones into zeros. Note that this will require at least $cnt_1$ operations.

Let $op = max(cnt_0, cnt_1)$. We can make the $A$ an $B$ equal in $op$ operations as follows.

  • Let $cnt_0 \geq cnt_1$. Take $cnt_1$ 0's and $cnt_1$ 1's in A and apply the XOR operation to swap 0's with 1's. After that you will be left with total $cnt_0 - cnt_1$ zeros elements to change to one. That you can do by taking each of these zeros with some single one and applying the OR operation.
  • Other case can be handled respectively.

Time Complexity:

$\mathcal{O}(n)$ for iterating over both the strings, where $n$ is size of strings $A$ or $B$.

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester

CHCOINSG - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Vasya Antoniuk
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

Simple

PREREQUISITES:

finding pattern, game theory, understanding of winning and losing positions

PROBLEM:

You have a pile containing $n$ coins. Two players play following game alternately. Each player in its turn can remove any prime power number of coins from the pile, i.e. $p^x$, s.t. $p$ is a prime and $x \geq 0$. The player who can't make his move loses the game. Find who wins the game.

QUICK EXPLANATION:

Second player will win iff $N \, \% \, 6 = 0$, otherwise first player will win.

EXPLANATION:

Solution based on finding pattern
We can find a pattern by writing a slow code to find the winner of the game for small numbers, say $\leq 100$. You can just implement the basic definition of winning/losing position in the game theory by writing a simple dp.

More formal solution
Let us try to see what happens for the game on some small examples.

For $n = 1$, first player will win.

For $n = 2, 3, 5$, first player will win as these numbers are prime.

For $n = 4$, the first player will also win as $4 = 2^2$.

For $n = 6$, player can not remove $6$ coins in his first turn, as $6$ is not a prime power. Hence, whatever number of coins first player removes, he will end up with $1, 2, \dots, 5$ coins, all of which are a wining positions for the other person. Hence, $n = 6$ is losing position for first player.

You can notice that numbers from $n = 7$ to $11$, are also winning positions, as the first player can make a move such that remaining number of coins in the pile are equal to 6, which is a losing position.

For $n = 12$, the first player can win if he can move to some losing position, i.e. he could remove either 6 or 12 coins. He can't remove any of these as they are not prime powers. So $n = 12$ is a losing position.

Similarly any multiple of $6$ is a losing position, as you can't make a move from $n = 6 * k$ to any losing position, as you have to remove coins equal to some multiple of 6. A multiple of 6 can't be a prime power, as 6 = 2 * 3.

Time Complexity:

$\mathcal{O}(1)$ - Just check whether $N \, \% 6 \, = 0$ or not.

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester
Editorialist

CHEFARK - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Dymtro Berezein
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

Easy

PREREQUISITES:

basic combinatorics, even-odd parity understanding

PROBLEM:

You have an array $A$ of $n$ integers. You can choose some element in the array and multiply it by -1. You have to do this operation total $K$ times. Find the number of different arrays you can end up with.

QUICK EXPLANATION:

The basic idea of the problem is to choose some elements in the array and multiply by -1's. Remaining operations can be done on a single element by making sure that its parity is not changed. If there exists a zero element in the array, the remaining operations can always be done on that element. In this case, the condition of making sure parity is unchanged is implicitly satisfied.

EXPLANATION:

Notice that the elements of the final array will be either same, or multiplied by -1. This means, that we can replace each number in the array with 0 (if the element is zero), 1 (if the element is positive), -1 (if it is negative).

The basic idea of the problem is to choose some elements in the array and multiply by -1's. Remaining operations can be done on a single element by making sure that its parity is not changed. If there exists a zero element in the array, the remaining operations can always be done on that element. In this case, the condition of making sure parity is unchanged is implicitly satisfied.

So, we will check whether we can change only some $x$ non-zero elements. If there exists a zero element in the array, then it can always be done. Otherwise, if $K - x$ is even, then also it can be done by applying the operation on same element multiple times. Number of ways of choosing $x$ elements out $n$ elements is denoted by $C(n, k)$ which can be found by precomputing factorials and finding inverse modulo a number.

Time Complexity:

$\mathcal{O}(n)$ or $\mathcal{O}(n \, log n)$ if you are finding inverse modulo in each call of $C(n, k)$

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester

FRJUMP - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Vadym Prokopec
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

medium

PREREQUISITES:

sqrt decomposition, log

PROBLEM:

You are given an array $a$ of size $n$. You have to answer following queries and update.

  • In each query, you are given two numbers - $i, r$. Let $prod = a_i \cdot a_{i + r} \cdot a_{i + 2 r} \cdot ... \cdot a_{i + k r}$, s.t. $i + k r \leq n$ and $k$ has largest possible value satisfying the equation. You to find $prod \pmod{10^9 + 7}$ and first digit of $prod$.
  • In the update operation, you can set $a_i$ to some value $v$.

QUICK EXPLANATION:

EXPLANATION:

Finding first digit and modulo value of product of some numbers
Finding product of some elements modulo some number is easy. Let us see how can we find the first digit of product of some elements. Note that direct multiplication could be very large and won't fit into any typical data type. Even if you use a big type, number of digits in the product could be huge and entire calculation will be quite slow.

As we know that sum of these elements would be quite smaller, so can we somehow represent the product of some numbers in terms of sum. We can take log of the product. Let $b_1, b_2, \dots, b_n$ be $n$ positive numbers. Let $prod = b_1 \cdot b_2 \cdot \dots \cdot b_n$. We get $log(prod) = log(b_1) + log(b_2) + .. \dots + log(b_n)$. So, given log of a number, can we find first digit of the number?
Yes, if we know the fractional part of the log value, we can get the first digit by calculating $10^{\text{fractional part}}$.
Fractional part of a double $x$ can be found by $x - floor(x)$.

Solution based on number of divisors of a number
Let us use 0 based indexing for the problem. For the given query of an integer $r$, we have to find first digit and modulo value of product $a_0, a_r, a_{2 * r}, a_{3 * r}, a_{k * r}$. Note that the indices are all multiples (including zero) of $r$. Due to this, we can realize that the update at index $i$ by setting $a_i$ to $v$, will modify the values of products for all $r$'s which are divisors of $r$ (0 is also counted).

Based on these observations, we can design a solution as follows.
Let $prod_r = a_0 \cdot a_r \cdot a_{2 * r} \cdot a_{3 * r} \cdot a_{k * r} \pmod{10^9 + 7}$.
Similarly, let $logSum[r] = log(a_0) + log(a_r) + log(a_{2 * r}) + \dots + \cdot a_{k * r}$.
Note that we can find the first digit of the product using $logSum[r]$ for a given query - $r$ as described above. In particular, it will be $pow(10, logSum[r] - floor(logSum[r])$.

For the given array, before processing all the queries, we can precalculate values of $prod_r and logSum_r$ for each $r$ from $1$ to $n$. Note that the time taken will be $\mathcal{O}(n log n)$.

Now let us see how to process the updates and query.

If we receive an update of setting $a_r$ to $v$, we will iterate over all the divisors $d$ of $r$ and update the corresponding $prod_d$ and $logSum_d$. Now if we receive a query of finding answer for given a $r$, we can directly answer it by using values of $prod_r$ and $logSum_r$.

Now, there is a small catch with the above solution. If we want to make an update at $r = 0$, then it will affect the answers of all the $prod$ and $logSum$ values. So if we directly update these values, we can take $O(n)$ in the worst case. To handle this case, we can separately maintain the value of first element, (i.e. $a_0$). So, whenever we receive an update of setting $a_0$ to some value, instead of changing all the $prod, logSum$ values, we will just change the value of first element we maintained. Note that we will have to change our update accordingly. For each query, we will have to additionally output the modified values of $prod$ and $logSum$ values respectively.

Note that this extra catch was because of the reason that $r = 1$ to $n$, all are divisors of 0. But for other numbers, this is not the case. Maximum number of divisors of a number $1 \leq n \leq 10^5$ are 128.

Hence, time complexity of this solution will be $\mathcal{O}(128 * n)$. Please note that in order to pass your solution with the given time limit, you have to implement this carefully, e.g. while update, don't calculate inverse of $a_r$ in the loop.

Time Complexity:

$\mathcal{O}(n \, 128)$

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester
Editorialist


SADPAIRS - Editorial

$
0
0

PROBLEM LINK:

Contest
Practice

Author:Kevin Charles Atienza
Testers:Istvan Nagy
Editorialist:Praveen Dhinwa

DIFFICULTY:

hard

PREREQUISITES:

tree dp, merging smaller component with largest component

PROBLEM:

You are given a graph network consisting of $n$ nodes and $m$ edges. $i$-th person uses color $c_i$. For each vertex $i$, you have to answer following quantity - assume If we remove $i$-th vertex, how many pairs of vertices with same colors will get disconnected. We call such pairs sad pairs.

QUICK EXPLANATION:

Solve the problem on a tree
Convert the given graph into block cut tree and now apply the algorithm for solving the problem on a tree.

EXPLANATION:

Solve on a tree
Let us first simplify the problem by solving it on a tree. Note that each vertex of tree will be an articulation point - a vertex in a connected graph is considered articulation point if removing it from the tree divides the graph into more than one disconnected components. To be more precise, all the non-leaf nodes will be articulation points.

Let us root the tree at any vertex (say vertex 1). Let us understand what will be number of sad pairs if we removing vertex 1. Let there be $child$ children of vertex 1. Consider a color $c$, Let $cnt_1$, $cnt_2, \dots cnt_child$ denote the number of colors $c$ all the children subtrees of vertex 1. Now number of sad pairs for this color will be sum of $cnt_i * cnt_j$ for $i < j$ childs.

Directly iterating over $i, j$ will take $O({child}^2)$ time. Instead, for each $j$, we can find sum of terms multiplied with $cnt_j$ efficiently. Essentially it will be $cnt_1, cnt_2, \dots, cnt_{j - 1}$. You can compute this quantity by maintaining a prefix sum. Pseudo codef follows.

sum[0] = 0
For j = 2; j <= child; j++)
    sad += cnt[j] * (sum[j])
    sum[j] += cnt[j]

So, now we know to how to find sad pairs for a given color. Finally total sad pairs will be sum of sad pairs for each distinct color.

Let us maintain a map<int, int=""> for each node $v$ in the tree - denoting the counts of various color in the subtree of $v$. So, the $key$ will correspond to color and the $value$ will denote the count of corresponding color in the subtree of $v$.

Now a we do a dfs from starting node $1$. In the dfs, we will maintain a map as described above. See the pseudo code

void dfs(from, parent):
    childs = {};
    for each neighbour to of from:
        if to = parent:
            continue
        childs.add(to);
        dfs(to, from)
    // Now at this stage, we will have maps for the childs computed.
    // Let us create corresponding map for vertex from using the child maps.
    map fromMap
    for each child c in childs:
        add map corresponding to c to fromMap

Time complexity of this solution will be $O(n^2)$ and similarly space complexity will also e $O(n^2)$. We need to optimize both space and time complexity.

Now, we will use a trick of merging smaller subtrees into the largest one at each node. For a very clear understanding of this trick, please see this nice tutorial. If possible, also solve the problems provided in the practice section.

For each node, let us call the child whose subtree has largest number of nodes as heavy child (if there are more than one childs, pick any of those). Call the remaining children as lighter children.

While computing map for a node, we will merge the maps of lighter children into the map of heavy child. Now, the map corresponding to the current node will be same as that of heavy child.

void dfs(from, parent):
    childs = {};
    heavy = none;
    maxSize = 0
    for each neighbour to of from:
        if to = parent:
            continue
        dfs(to, from)
        childs.add(to);
        if size[to] >= maxSize:
            maxSize = size[to]
            heavy = to
    // Now at this stage, we will have maps for the childs computed.
    // Let us create corresponding map for vertex from using the child maps, by merging the smaller maps into heavy child.
    let heavyMap = map corresponding to heavy map; // Please note that this is not equivalent to creating a copy. It is reference to that map.
    for each child c in childs:
        if c != heavy:
            for each (key, value) pair in map[c]:
                heavyMap[key] += value
    map[from] = heavyMap; // Please note that this is also not a copy. You have to make sure that this is a reference. In other words, make sure that memory used for map is same as that of heavyMap.

Let us consider an edge of the tree $(u, v)$ - $u$ is parent of $v$. We will call the edge heavy if $v$ is a heavy child of $u$, light otherwise.

Let us estimate time and space complexity of this approach. The key, value pair maintained for a color in vertex $v$ is moved into the heavy subtree of parent $u$, if $u$ is light child, i.e. the movement of $(key, value)$ pair is happending across the light edge.

Number of light edges in any path from root $1$ to any other vertex can be at max $\mathcal{O}(log n)$. Hence, it means that each $key$ will be moved at most $log n$ times.

Hence, it means that time complexity of this approach will be $\mathcal{O} (n log n) * log n \text{(for operations on map)}$.

Note that space complexity of this approach is $\mathcal{O}(n log n)$ too. Please note the very crucial point that when you have merged the ligher subtrees into heavy subtree, then you don't have to create an entirely new map having the content of merged subtree. You can just reuse the memory that you had allocated for heavy subtree. You can implement this by either using references or pointers etc. Please see various solutions for understanding details.

Solve the problem on a graph
We will find all the articulation points of the graph. Construct block-cut tree corresponding to the graph using these articulation points. Now, on this block-cut tree, we can apply the same algorithm as previous one to solve the problem. Note that you don't need to construct the tree explicitly, you can use the tree strcuture implicitly, see the code of tester for details.

Please note that I have skipped some details on how to compute the sad pairs using the maps created for each subtree. These details should be relatively easier to figure out.

Time Complexity:

$\mathcal{O}(n + m)$ (for finding block-cut tree) + $\mathcal{O}(n * n {log n}^2)$ for solving the problem on created tree.

AUTHOR'S AND TESTER'S SOLUTIONS:

Setter
Tester

ASP - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Jingbo Shang
Tester:Xiaoxu Guo
Editorialist:Pushkar Mishra

DIFFICULTY:

Simple

PREREQUISITES:

Ad-hoc

PROBLEM:

Given an array $A$, output "YES" if the array is sortable by moving the elements at maximum one index from their respective positions, otherwise output "NO".

EXPLANATION:

The given array is indexed from 1 to $N$. We maintain an auxiliary array $Mark$ which is initially set to 0.

Now, let us consider the first two elements of the array, i.e., $A[1]$ and $A[2]$. If $A[1] \leq A[2]$ then we needn't do anything. However, if $A[1] > A[2]$ then we need to swap $A[1]$ and $A[2]$. If we swap $A[1]$ and $A[2]$, we change $Mark[2]$ from $0$ to $1$. Doing so tells us that the element at position 2 wasn't at this position in the original array.

Next we consider elements at positions $A[2]$ and $A[3]$. If $Mark[2] = 1$, this would mean that the element at position 2 actually came from position 1. Since it has already been moved from its position, it can't be moved to the further right. This tells us that if $Mark[2] = 1$ and $A[2] > A[3]$, then the array can't be sorted according to the given rules. On the other hand, if $A[2] \leq A[3]$, then we simply go onto the next pair of elements, i.e., $A[3]$ and $A[4]$. If $Mark[2] = 0$ and $A[2] < A[3]$, then we swap $A[2]$ and $A[3]$, change $Mark[3]$ from $0$ to $1$ and again proceed to considering the next pair of elements, i.e., $A[3]$ and $A[4]$.

This gives us the first part of our algorithm:

func sortable(A)
{
        Mark = {0};

    for (int i = 1 to N-1)
    {
            if (A[i] > A[i+1] and Mark[i] == 1)
            {
                    return false;
            }
            else if (A[i] > A[i+1])
            {
                    Mark[i+1] = 1;
            }
    }

    /* MORE CODE TO BE ADDED. READ ON! */

    return true;

}

The function isn't complete. It only checks whether the swaps made were valid are not. There is one more thing we need to check before we can return true. After all the swaps have been made and the function hasn't returned false, we need to check whether the array is actually sorted or not. Thus, the complete algorithm is as follows:

func sortable(A)
{
        Mark = {0};

        for (i = 1 to N-1)
        {
                if (A[i] > A[i+1] and Mark[i] == 1)
                        return false;

                else if (A[i] > A[i+1])
                        Mark[i+1] = 1;
        }

        for (i = 1 to N-1)
        {
                if (A[i] > A[i+1])
                        return false;
        }

        return true;
}

COMPLEXITY:

$\mathcal{O}(N)$ per test case.

SAMPLE SOLUTIONS:

Author
Tester
Editorialist

AMR15B - Editorial

$
0
0

PROBLEM LINK

Practice
Contest

Panel Members

Problem Setter:Suhash
Problem Tester:Editorialist:Sunny Aggarwal
Contest Admin:
Russian Translator:
Mandarin Translator:
Vietnamese Translator:
Language Verifier:

DIFFICULTY:

Medium

PREREQUISITES:

Fermat little theorem, Number Theory, Subset Theory, Mathematics.

PROBLEM:

Given an array $A$ consisting of $N$ integers where, each value $A_i \le 10^5$. We are asked to calculate the product of gcd of all non empty subset of array $A$ modulo $10^9 + 7$.

EXPLANATION

Let us solve the following simpler problem first in order to understand the solution of original problem better.

Problem Statement Given an array $A$ consisting of $N$ integers where, each value $A_i \le 10^5$. For each number $i$ where $i \in (1, 10^5)$, calculate the number of non empty subsets with gcd = i modulo $10^9 + 7$.

Lets create an array $S[]$ where $S_i$ will contain the number of non empty subsets with gcd = i and an array $F[]$ where $F_i$ will contain the number of elements among given $N$ elements that are multiple of $i$.

How to construct array $F$ ?

It is given that each value in the array $A$ i.e $A_i \le 10^5$. Therefore, we can simply pre compute the divisors for a given $i$ where $i \in [1, 10^5]$ and use following algorithm to fill array $F$.

C ++ Code

vector<int> div[ 100000 ];
void pre() {
    for(int i=1; i<=100000; i++) {
        int j = i;
        while( j <= 100000 ) {
            div[j].push_back( i );
            j += i;
        }
    }
}

int F[100000]; void solve() { int n; cin >> n; for(int i=1; i<=n; i++) { int x; cin >> x; for( auto it: P[x] ) { F[it] ++; } } }

$F_x$ stores the count of numbers which are multiple of $x$. Therefore, choosing any non empty subset of these numbers will produce gcd of any of these kind $x$, $2*x$, $3*x$ ... and so on ( multiples of $x$ ) and if we know how many subsets are there which produces gcd = $2*x$, $3*x$, $4*x $... and so on in advance, we can evaluate the number of subsets with gcd = x easily.

Above explanation is easy to understand with the following code.

void solve() {
    for(int i=100000; i>=1; i--) {
        int remove = 0;
        int j = 2 * i;
        while( j <= 100000 ) {
            remove += S[j];
            remove %= mod;
            j += i;
        }
        int total = (power(2, F[i]) - 1); // number of non empty subsets
        S[i] = total - remove; // removing subsets with gcd 2 * i, 3 * i...
        if( S[i] < 0 ) {
            S[i] += mod;
        }
    }
}

Hurray !! We have solved the simpler version of our original problem.

At this point, we know for each value $x \in [1, 10^5]$, the number of subsets with gcd = x in $S_x$ and our original problem asked for the following expression

$$Answer = \bigg(\prod_{\substack{x \in [1, 10^5]}}{x^{S_x}}\bigg) \% 10^9+7$$

Note that if a given $x$ can't be gcd of any subset, then $S_x$ = 0 and therefore it is correct to write above expression.

How to compute above expression ?

We cannot compute this expression easily as value of $S_x$ can be very large. So, we will be using Fermat Little Theorem here. Fermat's Little theorem states that $a^{p-1} = 1$ mod $p$. Where $p$ is prime. This is valid for all integers $a$. So if we want to calculate $a^b$ mod $( p )$ and $b = k * (p-1) + m$. Then we know $a^b = (a^{p-1})^k * a^m = 1^k * a^m = a^m$ and therefore, we will be maintaining array $S[]$ modulo $(10^9 + 6)$ instead.

Please have a look at editorialist's solution for implementation details.

COMPLEXITY

$O(T*max(A_i) * \log(A_i))$

SIMILIAR PROBLEMS

Bokam and his gcd

Multipliers

Coprime Triples

FCBARCA - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Bruno Oliveira
Tester:Hiroto Sekido
Editorialist:Anton Lunyov

DIFFICULTY:

SIMPLE

PREREQUISITES:

Simple Math

PROBLEM:

Let Messi have index 0, while all other players have indexes from 1 to K.
Denote as f[n][x] the number of sequences {a[0], a[1], ..., a[n]} of integers such that:

  • 0 ≤ a[j] ≤ K for j = 0, 1, 2, ..., n;
  • a[0] = 0, a[n] = x;
  • a[j−1] ≠ a[j] for j = 1, 2, ..., n.

We need to find f[N][0] mod P, where P = 1000000007.

QUICK EXPLANATION:

Let K be fixed and g[n] denotes f[n][0] mod P. Then g[0] = 1, g[1] = 0 and
g[n] = ((K − 1) * g[n−1] + K * g[n−2]) mod P for n ≥ 2.
See EXPLANATION for proof.

So the problem can be solved using simple loop. But be careful with modular arithmetic. The following code:

g[n] = ((long long) (K-1) * g[n-1] + (long long) K * g[n-2]) % 1000000007;

is safe at C++ for calculating g[n] for the above recurrence. Not writing long long will cause int overflow.

Alternatively the problem can be solved using formula (KN + K * (−1)N) / (K + 1). But using this formula requires either inverse residue modulo P or arbitrary precision arithmetic. So use it on your own risk :)
See ALTERNATIVE SOLUTION for details.

EXPLANATION:

At this section we justify recurrence for g[n].
It is clear that f[0][0] = 1 and f[0][x] = 0 for x = 1, ..., K.
Basic combinatorial reasoning yields that f[n][x] for n > 0 is the sum of f[n−1][y] for all y from 0 to K, inclusive, such that y ≠ x. Indeed, term a[n−1] can be any number from 0 to K, inclusive, except x. So after fixing y = a[n−1] and deleting a[n] we get the arbitrary sequence that is counted by f[n−1][y].

The constraints are very soft. So even such quadratic DP will pass the TL, but we continue further.
It is clear that f[n][1] = f[n][2] = ... = f[n][K] since all players except Messy are non-distinguishable by the above definition. Hence denoting g[n] = f[n][0] and h[n] = f[n][1] we can get the following formulas for g[n] and h[n]:

g[n] = f[n][0] = f[n−1][1] + ... + f[n−1][K] = K * h[n−1];

h[n] = f[n][1] = f[n−1][0] + f[n−1][2] + ... + f[n−1][K] = g[n−1] + (K−1) * h[n−1].

Summarizing we get:
g[0] = 1, h[0] = 0,
g[n] = K * h[n−1],
h[n] = g[n−1] + (K−1) * h[n−1].

By theses formulas we already get simple O(N) solution (refer to the tester's solution).
But we can get another simplification.
Multiplying formula for h[n] by K we get:
K * h[n] = K * g[n−1] + (K−1) * (K * h[n−1]).
Note that K * h[n] = g[n+1] and K * h[n−1] = g[n].
Hence we get
g[n+1] = K * g[n−1] + (K−1) * g[n] for n > 1.
Together with g[1] = K * h[0] = 0 we get the solution described in the QUICK EXPLANATION section.

Note also that using exponentiation by squaring for 2 × 2 matrices we can solve the problem in O(log N) time using recurrent formulas for g[n] and h[n]. Most of the related problems listed below require similar considerations but also require some advanced technique like exponentiation by squaring in the end.

ALTERNATIVE SOLUTION:

Here we prove the explicit formula mentioned in the QUICK EXPLANATION section.
We apply the basic theory of linear homogeneous recurrence relations with constant coefficients to the recurrent sequence g[n]. For this we write down the characteristic polynomial:

p(t) = t2− (K−1) * t − K.

Its roots are r1 = −1 and r2 = K. Hence the general solution for this recurrence is

g[n] = C1 * r1N + C2 * r2N = C1 * (−1)N + C2 * KN.

Constants C1 and C2 can be found from relations g[0] = 1, g[1] = 0.
Namely, substituting n = 0 and n = 1 to the general form of g[n] we get

 C1 + C2 = 1;
−C1 + K * C2 = 0.

Solving this 2 × 2 system we get C1 = K / (K + 1) and C2 = 1 / (K + 1).
Hence g[n] = (Kn + K * (−1)n) / (K + 1) and we are done.

The simplest way to use this formula is to use language with built-in arbitrary precision arithmetic like Java or Python and calculate the above expression directly and then take it modulo P in the end.

AUTHOR'S AND TESTER'S SOLUTIONS:

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

RELATED PROBLEMS:

Codeforces Round #113 (Div. 2) - Problem E - Tetrahedron
NEWSCH
CKISSHUG
CROWD
CSUMD
CHESSGM
HAREJUMP
CAKEDOOM

ANUBTG - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Anudeep Nekkanti
Tester:Minako Kojima
Editorialist:Lalit Kundu

DIFFICULTY:

EASY

PRE-REQUISITES:

Sorting, Greedy

PROBLEM:

You have to buy N items of cost A1, A2 ... AN. For every two items you buy, they give you two items for free. However, items can be of varying price, they always charge for 2 most costly items and give other 2 as free. For example, if the items cost 1, 1, 2, 2, then you have to pay 4 and take all 4 items.
Find minimum price in which you can buy all items?

QUICK EXPLANATION:

Sort the array A and greedily start choosing from largest elements.

EXPLANATION:

Claim 1:

We should pick the most costliest and second most costliest items in a single bill.

Proof:

Assume x be the most costliest item and y be the second most costliest item. Assume x and y are in different bags. There can be two cases.
- The bag containing x, has only one element.
We can add y in the same bill too because we are anyway paying for both, so why two separated bills instead of one.
- The bag containing x, has more than element. Assume z be the second most costliest item in bag containing x.
Now we can simply swap y and z. So we will end up x and y being in same bag. Also due to this swapping, there is no change in cost because we were anyway paying for both x and y before.

After picking the most costliest items in a single bill, we should try to pick the third and fourth most costliest items also in the same bag to get most benefit of buy 2, get 2 free scheme. As the third and fourth items will be free.
We can even formally prove this part similar to swapping item used in previous claim.

This concludes the mathematical proof required.

Now that we have chosen one group we'll choose further groups from remaining array A.

This is the design of our greedy algorithm. We sort the array A first and then start choosing groups of 4 in decreasing order of array A. This will ensure that we make minimum sum.

Pseudo code:

A = input
sort(A)
reverse(A)
ans = 0

for i=0 to N-1:
    //count in answer the index 0,1,4,5,8,9...
    if i%4 < 2:
        ans += A[i]

print ans

Complexity: O(N log N) due to sorting.

SOLUTIONS:

Setter's solution
Tester's solution

Viewing all 39796 articles
Browse latest View live


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