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

SNGRAPH - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Hussain Kara Fallah
Tester:Hasan Jaddouh
Editorialist:Sidhant Bansal

AUTHOR'S AND TESTER'S SOLUTIONS:

AUTHOR's solution: Here
TESTER's solution: Here

DIFFICULTY - Medium

PREREQUISITES - DSU (Disjoint Set Union)

PROBLEM - Given a graph of $N$ nodes and $M$ edges. For all $d$ from $0$ to $N - 1$ calculate the minimum no. of edges that need to be added to make the graph connected, when all the edges whose at least one end point has degree less than or equal to $d$ is deleted.

QUICK EXPLANATION -

This question requires DSU and basic graph theory. We can simulate the process in reverse order, that is from $d = N - 1$ to $d = 0$, doing DSU of components and the answer for every $d$ is the no. of components - 1.

EXPLANATION -

Firstly we would make an array of vectors, where in the $x_{th}$ vector we store all the nodes whose degree is $x$.

Observation 1 - For any disconnected graph we can easily prove that the minimum no. of edges needed to be added to make the graph connected is equal to the no. of components - 1. Suppose we have arranged the components in line from left to right. Now you can merge any two adjacent components by adding an edge. So, you will require no. of components - 1 edges to be added.

The naive approach for this question would be to loop for $d$ from $0$ to $N - 1$, and for each $d$ make the new graph with the deleted edges and do multiple DFS on this new graph to count the total no. of components and then print the answer as no. of components - 1.

But this can be optimised using the second critical observation which is -

Observation 2 - If we process $d$ in reverse order, i.e from $N - 1$ to $0$ then it is more efficient because the edges would only be added and not destroyed, which is a feature that DSU can support. The intuition behind this method is that for each $d$ all the edges to be deleted are a union of those that need to be deleted for $d - 1$ along with some other edges specific to this $d$. This shows us that it is actually a completely disconnected graph, i.e all the nodes have $degree = 0$, when $d = N - 1$. And as the $d$ is decreased, more and more edges are added. Now when $d$ moves from $d = x$ to $d = x - 1$, then all the nodes having $degree = x$ are activated and processed (in simple term the edges which have one end point as these nodes are undeleted), which can be supported by the DSU.

So for the expected solution we actually process $d$ from $N - 1$ to $0$ and for each $d$ we first store the current no. of components - 1 as the answer for this $d$ and then activate all the nodes that are in the $d_{th}$ vector, i.e all the nodes that have degree exactly equal to $d$. Now we process these activated nodes, here processing a node means to join that node to all its immediate neighbours which are active using DSU and we need to constantly maintain the count of the total no. of components while performing DSU.

Refer to the given below C++ implementation for more details -

#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;

vector<int> adj[N], V[N];
int deg[N], p[N], sz[N], ans[N];
bool active[N];
int components;

int par(int x){
    if(p[x] != x)   p[x] = par(p[x]);
    return p[x];
}

void dsu(int a, int b){
    int p1 = par(a), p2 = par(b);
    if(p1 == p2)    return ;
    if(sz[p1] < sz[p2]) swap(p1, p2);
    sz[p1] += sz[p2];
    p[p2] = p1;
    components--;
}

void solve(){

    for(int i = 0; i < N; i++){
        adj[i].clear();
        V[i].clear();
        deg[i] = 0;
        active[i] = 0;
    }

    int n, m, u, v;

    cin>>n>>m;
    while(m--){
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);

        deg[u]++, deg[v]++;
    }

    components = n;
    for(int i = 1; i <= n; i++){
        p[i] = i, sz[i] = 1;
        V[deg[i]].push_back(i);
    }

    for(int i = n - 1; i >= 0; i--){
        ans[i] = components - 1;
        for(auto u : V[i])  active[u] = 1;
        for(auto u : V[i]){
            for(auto v : adj[u]){
                if(active[v] == 0)  continue;
                dsu(u, v);
            }
        }
    }

    for(int i = 0; i < n; i++)  cout<<ans[i]<<" ";
    cout<<endl;
}

int main(){
    int t;
    cin>>t;
    while(t--)  solve();
}

Time Complexity -

The time complexity of an operation in DSU with path compression is $\alpha(n)$ and the no. of times it is done is equal to the number of edges in the graph. Therefore the complexity of the solution is $O((N + M) * \alpha(N))$. Since the $\alpha(n)$ is a small constant (around 4) for all practical values of $N$ therefore it can be ignored as a constant factor also in the complexity analysis.

AUTHOR'S AND TESTER'S SOLUTIONS:

AUTHOR's solution: Here
TESTER's solution: Here


PRMQ - Online solution June 17 (unofficial)

$
0
0

Problem Link

Contset Link

Practice Link

Prerequisites

Prime Factorization, Binary Search, Segment Tree/ Merge Sort Tree

Quick Overview

Given N numbers and Q queries, for each query find sum of number of prime numbers which are between X to Y (both inclusive) in prime factorization of numbers from L to R (both inclusive).

Solution

As this is not official editorial i directly jump to full solution. for subtask 1 brute force should pass, for second subtask my sqrt solution gets 30 points linked below.

100 points

The idea is to use Segment Tree pretty much like standard one but with few modifications. Like in normal Segment Tree for sum queries, in each node we store sum of numbers for range represented by the node, here we store prime numbers in prime factorization of numbers represented by range of that node and also maintain count of prime numbers.

For fast queries using binary search we store it in sorted order and calculate prefix sum for each node later.

Building the Segment tree:

Let's start with leaf nodes which represent one number, as stated above we store primes in it's factorization and their count in sorted order let say we store in an array then it's maximum size can be 8 as 21 * 3 1 * 51 * 71 * 111 * 131 * 171 * 191> Max(a[i]).

Now we build inner nodes, they just contain primes in list of their sons. which is like merging list of sons into one. let's find length of list contained in these nodes let it represents range of length L also for worst case let no prime factor is common among those elements so max length can be 8 * L as each may have at most 8 prime factors.

check build function for details

complexity analysis: O(NlgN)

merging 2 lists of length O(L/2) takes O(L) time.

at level 1, 1 node of length N => take O(N) time.

at level 2, 2 nodes of length N/2 => 2 * O(N/2) = N

...

...

at last level N node of length 1 => N * O(1) = N

summing at each level gives total O(NlgN) time complexity for building.

similarly

Memory complexity: O(NlgN)

Query:

Let say we have query L, R, X, Y as given in problem. It's same as normal one except one modification, from each node that is queried we want sum of count of primes between Y to X, binary search is used here.

check query function.

complexity: O(lg2N)

Code:

Sqrt solution code for subtask 1 and 2.

Segment Tree/Merge Sort Tree like code full solution.

this is my first blog post feel free to ask in comments

Help in CANDY123

$
0
0

hey guys...I am trying to solve CANDY123 and i am getting my test cases correct but it gives me wrong answer when i submit. can anybody tell me what test cases should i try to resolve this problem. Thanks.. :)

` #include<iostream> #include<sstream> #include<string> #include<limits>

using namespace std;

int main()
{
    int trials = 0;
    cin >> trials;
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    while(trials--)
    {
        int A = 0;
        int B = 0;
        string line;

        getline(cin,line);

        stringstream s(line);

        s >> A >> B;


        int l = 0;
        int b = 0;
        int candy = 1;
        int turn  = 0;
        while(true)
    {
        if (turn)
        {
            if(b <= B)
        {
            b += candy;
            turn  = 0;
        }
            else
        {
            cout<<"Limark"<<endl;
            break;
        }
        }
        else
        {
            if(l <= A)
        {
            l += candy;
            turn = 1;
        }
            else
        {
            cout<<"Bob"<<endl;
            break;
        }
        }
        candy++;
    }
      }
  }

`

GERALD04 - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Gerald Agapov
Tester:Tasnim Imran Sunny
Editorialist:Jingbo Shang

DIFFICULTY:

Cakewalk

PREREQUISITES:

Programming

PROBLEM:

GF --- (t2 - t1) --- Chef --- dist --- Home

Given t1, t2, dist, determine the time costs before GF see the gift of two plans:

  1. Chef waits for GF, and then goes home together.
  2. Chef returns home first, and goes back to GF.

EXPLANATION:

For the first plan, the answer should be (t2 - t1) + dist.

For the second one, it will be a little complicated. We need to discuss in 2 cases:

  1. If dist + dist <= t2 - t1, then Chef can return the bus station before GF arrived. Therefore, the answer should be t2 - t1.
  2. If t2 - t1 < dist + dist, then they will meet at the trip of going back. Therefore, the answer should be the middle point of the trip (imagine that the three parts as a whole): (t2 - t1 + dist * 2) / 2.

AUTHOR'S AND TESTER'S SOLUTIONS:

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

Problem with JULKA

$
0
0

I don't know why my solution is wrong for a SPOJ problem the problem name is JULKA.

Problem link is this.link text

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>
#include <vector>

using namespace std;
int main()
{
    int t=10,a,b;
    while(t--) {
               cin>>a>>b;
               int x,y;
               //x+y = a;
               //x-y = b;
               cout<<(a+b)/2<<"\n"<<(a-b)/2<<endl;
    }
    return 0;
}

Please help me to find the exact solution of this problem.

How to solve codeforces Bits problem?

MGCHGYM - Editorial

$
0
0

Problem Link

Practice
Contest

Difficulty

Medium-Hard

Pre-requisites

Treap, bitset, DP

Problem

Maintain two types of modifications on the given array and solve the subset-sum problem on its' subsegments.

How to get 25 points

For the beginning, let's focus on the solution to the first subtasks. The constraints are rather small, so all the modifications can be done naively, in the straightformard way. Namely, if you need to change the value of an element, you can do this in O(1) time, and when you need to reverse the subarray, straightforward O(N)-per-reverse approch will do.

Let's deal with the queries of the third kind.

The following simple DP technique will help us to determine - whether it is possible to get W as the sum of some of these numbers or not. First of all, pseudocode:

fill dp[] with zeroes dp[0] = 1 for i = L; i <= R; ++i for j = W; j >= a[i]; --j dp[j] |= dp[j - a[i]]

Now, let's have a closer look to the provided code. Suppose that we operate on the array a[]. The value of dp[k] will be equal to one if it is possible to collect the sum of k from the given integers and will be equal to zero otherwise. Initially, only dp[0] is non-zero.

Then, step by step we recalculate the values of dp[] by adding the integers from the given set one-by-one. The value of dp[j] will become equal to one during the adding of the ith element (say a[i]) if it was possible to collect a sum of (j - a[i]) before. Of course, we consider that j ≥ a[i].

The whole complexity of the described solution is O(NQ+PNW) or simply O(N(Q+PW)).

This solution will be sufficient to solve the first and the second subtasks.

How to get 50 points

At this point, we won't speed the modifications up, but will improve the execution time of the subset-sum part.

For doing this, we will have two crucial optimizations.

The first optimization

Now it's time to remember that there are only K ≥ 10 types of the element of the array a[] (aka weight-plates). During each of the subset-sum queries we process R-L+1 elements of a[] which can be optimized to O(K log (N / K)) = O(K log N) - considering the small value of K it will be good.

Let's calculate the number of weight plates of each kind. Now, consider a single kind of weight plates and suppose that there are X plates of this kind. Let's create the new summands for our subset-sum problem by grouping the weight plates:

  • The first summand should be equal to the weight of one weight plate;
  • The second summand should be equal to the weight of two weight plates;
  • The third summand should be equal to the weight of four weight plates;
  • And so on: the ith summand should be equal to the weight of 2(i-1) weight plates;

At some moment, you won't be able to create one more summand. This moment is when the amount of the weight plates you need for the new group is greater than the amount of the weight plates that are left. In this case, the last group should contain all the remaining weight plates.

Now, let's consider some examples of making the groups for the different amount of weight plates:

  • If you have 1 weight plate, there will be a single group containing this weight plate;
  • If you have 2 weight plates, there will be two groups, each containing a single weight plate;
  • If you have 3 weight plates, there will be two groups - the first containing a single weight plate and the second containing two weight plates;
  • If you have 4 weight plates, there will be three groups - the first containing a single weight plate, the second containing two weight plates and the third, again, containing a single weight plate.
  • Finally, if you have 100 weight plates, there will be 7 groups, containing 1, 2, 4, 8, 16, 32 and 37 weight plates respectively.

This way, for each kind of the weight plates, you will have no more than O(log N) summands that results in O(NQ + PWK log N) complexity.

The second optimization

Consider the version of the subset-sum DP that was shown in "How to get 25 points" part. You can note that all the elements of dp[] are either ones or zeroes and the operations on them are binary - to be more precise, only binary OR.

This enables us to use bitset, so we can speed the code up in 32 times.

Now we've got O(NQ + PWK log N / 32) solution that can additionally solve the third subtask. Such solution gets 50 points.

Getting full points

We've already achieved O(NQ + PWK log N / 32) complexity. Let's note that for the constraints of the problem the O(PWK log N / 32) part is already small enough. That means that now we process the queries of the third kind fast enough. Now we need to improve the processing of the queries of the first and the second kind.

Both these queries are actually correspond to a very standard problem - maintain the array under the following queries:

  • Reverse a subarray of the array in O(log N) time;
  • Change the value of a single array's element in O(log N) time;

This problem is easily solvable with a data structure called treap.

In our problem, there is one more query that should be maintained:

  • Find the amount of the weight plates of each kind on a given segment

For doing this, we can simply store an array of K elements in each node of the treap, where the ith element of this array will denote the number of the weight plated of the ith kind on the corresponding segments. That gives us O(K log N)-per-modification time for the modification query of the both - the first and the second kinds.

Eventually, we get the complexity of O(QK log N + PWK log N / 32). This solution passes all the subtasks and gets 100 points.

Setter's Solution

Can be found here

Tester's Solution

Can be found here

Tries deletion in c++

$
0
0

Hi folks, I have been reading tries implementation in c++ and stuck in tries deletion part. Here is the link to the article: http://www.geeksforgeeks.org/trie-delete/ I'm confused on this statement in recursive part :

return ( !leafNode(pNode) && isItFreeNode(pNode) );

Here is the code for deletion I have been reading on geeks for geeks.Pls, help me out in recursive part.

bool deleteHelper(trie_node_t *pNode, char key[], int level, int len)
{
    if( pNode )
    {
        // Base case
        if( level == len )
        {
            if( pNode->value )
            {
                // Unmark leaf node
                pNode->value = 0;

                // If empty, node to be deleted
                if( isItFreeNode(pNode) )
                {
                    return true;
                }

                return false;
            }
        }
        else // Recursive case
        {
            int index = INDEX(key[level]);

            if( deleteHelper(pNode->children[index], key, level+1, len) )
            {
                // last node marked, delete it
                FREE(pNode->children[index]);

                // recursively climb up, and delete eligible nodes
                return ( !leafNode(pNode) && isItFreeNode(pNode) );
            }
        }
    }

    return false;
}

Facing No Such Element Exception in JAVA

$
0
0

why my code https://www.codechef.com/viewsolution/14259829 is gives ERROR on "RUN" and WRONG ANSWER on "SUBMIT" for SNAKPROC........ The error is Exception in thread "main" java.util.NoSuchElementException at java.util.Scanner.throwFor(Scanner.java:862) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at Codechef.main(Main.java:14)

Can anyone help me with Number of Factors problem?

Regarding C++ stl- set.

$
0
0

Hey guys, i need some help/clarification on sets.

(I searched for this but couldnt find anything relevant. Hence i would be grateful if you guys could help ^_^ )

Its with reference to problem XORSUB 's solution here which used the method of Gaussian Elimination .

With reference to that solution, there is a comment-

The logic is correct. But there is small flaw in implementation. The above code will give wrong output for following test case

1
3 1
12 10 8
This is because of how STL set works. For correct result, just swap these two statements

s.erase(t);
s.insert(t^m);

Why is this in this way? What is the effect of swapping the two statements? What error is caused in this method and how does swapping fix this? The usual pages on sets dont mention this anywhere, and I feel such exceptional cases should be known to the coder. I would be grateful if anyone can explain this ^_^

June Long -Triplets (TLE)

snackdown'17 qualifer certificates?????

$
0
0

when will we get the snackdown 2017 qualifer round certificates????

Wrong answer in XMAX Spoj question

$
0
0

I was solving XMAX question of Spoj using Gaussian elimination method to find the max subset xor of an array. But it's giving me WRONG answer after passing through few testcases,don't to why? Most surprisingly XORSUB question of Codechef(which is nearly same as XMAX, just have difference of initializing ans=0 and ans=k) is giving me Right answer on codechef.

Here are links:
XMAX question: http://www.spoj.com/problems/XMAX/.
My XMAX solution: http://ideone.com/UbRCH9
XORSUB question: https://www.codechef.com/problems/XORSUB.
My XORSUB solution: https://www.codechef.com/viewsolution/14208798

Please help me solve Euler Sum

$
0
0

I tried solving Euler Sum in June Long contest but was not able to. I had no clue how to start. Can someone give me some idea on how to approach the same.


Tutorials for June long challenge 2017

$
0
0

Where are the tutorial for June challenge 2017? I can only see some unofficial tutorial among which I found 1 to be wrong! And also please add the tutorial link to the contest page.

MCO16404 - Editorial

$
0
0

PROBLEM LINK:

PracticeContest

Author:Zi Song Yeoh

DIFFICULTY:

EASY-MEDIUM

PREREQUISITES:

BINARY SEARCH, TRIES, SEGMENT TREES

PROBLEM:

Given $Q$ queries $(l, r, x)$, find the maximum value of $a_{j} \otimes x$ where $l \le j \le r$.

EXPLANATION:

The first subtask is trivial : You can just iterate through all elements in range for each query to find the answer.

The third subtask has $x = 0$, which reduces the problem to Range Maximum Query, which can be solved with Sparse Table or Segment Trees in $O(n\log n)$.

Now, let's see how to solve the second subtask. One way to solve this is by building a trie (though it's not neccesary and the same solution can be applied to the sorted array of numbers instead). Build a trie for all the numbers in range $[l, r]$. We walk down the trie from the root. Whenever we have a choice of whether to go left or right, we pick the choice that maximizes the final xor value, i.e. if the current bit of $x$ is $0$, choose the path that is labelled $1$ and vice versa. Thus, each query can now be solved in $O(\log n)$ time.

We can generalize this idea to solve the whole problem. What we need here is a segment tree of tries (or segment tree of sorted arrays is sufficient in this case). We can build a trie for each segment of the segment tree in $O(n\log n\log a_{i})$ time and for each query, we need to query the trie in $O(\log n)$ segments. Thus, the whole solution would work in $O((n + q)\log n\log a_{i})$ time.

AUTHOR'S AND TESTER'S SOLUTIONS:

Author's solution can be found here.

Tester's solution can be found here.

RELATED PROBLEMS:

June 2017 long: Problem PRMQ?

$
0
0

Hey guys, Can you explain your approach to solve PRMQ from june 17 long? I am aware BIT is being used in most solutions. I am not able to decipher how the thing works. Thanks!

NPTEL video downloader Chrome Extension

$
0
0

Hello, everyone, I developed Chrome extension for downloading entire video course in a single click. The current process is tedious and time-consuming. I hope you'll find it helpful. Please share with others. here is the link

Here's a blog

Can anyone help me with SUMQ from JUNE17 ?

Viewing all 39796 articles
Browse latest View live