CHFQUEUE - Editorial

PROBLEM LINKS :

Practice

Contest

Author and Editorialist Vineet Paliwal
Tester Roman Rubanenko

DIFFICULTY :

Cakewalk

PREREQUISITES :

Stacks , Queue , Modulo , Modular Arithmetic , Modular Multiplication

PROBLEM :

Given N chefs in a queue , each chef may delegate his/her task to the junior least ahead of him and go away . The Head Chefs fearfulness of the scenario is the difference in index of the two positions + 1 . Head Chef’s total fearfulness is product of individual fearfulness corresponding to each chef . Find total fearfulness . In case no junior lies ahead the fearfulness is 1 .

EXPLANATION:

The Naive Solution :

For each chef look at all chefs ahead of this chef in the queue till you find a junior chef and then update the Head Chef’s fearfulness . This has a time complexity of O(N^2) .

Using Stacks :

Start with given queue and an empty stack(of a structure of numbers and their indexes) .
For each chef put him on a stack if the top of stack is not senior to him otherwise pop out as many senior chefs from the stack as possible ( updating Head Chef’s fearfulness at each pop ) and finally push the chef on the stack .
The time complexity of this solution is O(N) .

Example Using Stacks :

Given the queue , 8 3 7 8 9 12 13 11 3 4

Initialize ans = 1 ; sp = 1000000007

Step One : Stack == [8,1]

Step Two : Stack == [3,2] ( ans *= ( 2 - 1 + 1 ) , ans %= sp => ans = 2 )

Step Three : Stack == [3,2] [7,3] ( ans remains same )

Step Four : Stack == [3,2] [7,3] [8,4] ( ans remains same )

Step Five : Stack == [3,2] [7,3] [8,4] [9,5] ( ans remains same )

Step Six : Stack == [3,2] [7,3] [8,4] [9,5] [12,6] ( ans remains same )

Step Seven : Stack == [3,2] [7,3] [8,4] [9,5] [12,6] [13,7] ( ans remains same )

Step Seven : Stack = [3,2] [7,3] [8,4] [9,5] [11,8] ( Two elements are popped out , ans need to be multiplied by 2 and 3 corresponding to each of pop . So ans = 12 )

Step Eight : Stack == [3,2] [3,9] ( Four elements are popped out . ans need to be multiplied (modularly) by 2 , 5 , 6 , 7 )

Step Nine : Stack == [3,2] [3,9] [4,10] .

Finish and output ans .

Point to Remember :

Take modulus with the special number given after each multiplication .

SETTER’S SOLUTION

TESTER’S SOLUTION

3 Likes

The stack-based solution is nice. Another simple solution (but with an O(N * log(K)) time complexity) is based on using a segment tree. Let’s build a segment tree over the K levels of seniority. Then we will traverse the chefs from N down to 1. For each chef i we need to find the smallest position associated to a level between 1 and a(i)-1. In the segment tree we will maintain for each leaf y from 1 to K the smallest position of a chef with level y. Thus, we only need to perform a query on the interval 1…a(i)-1 for the minimum value in this interval. After finding the answer for chef i we need to update the value stored in the segment tree for the leaf a(i) (because i is the current smallest position of a chef with level a(i)). Initially we will assume that each value associated to a leaf of the segment tree is +infinity (i.e. a very large value).

4 Likes

i have tested a lot of cases on my system and i m gettin right answer…bt i m getting WA for my solution on submission
plz help… following is the link to my solution CodeChef: Practical coding for everyone

1 Like

@mugurelionut : Lunch time being for school students we try that problems be doable with simple concepts . It is difficult to prevent O(N log N) and O(N log K) solutions from passing when O(N) is expected complexity , especially in lunch time because we have to allow a good buffer time for poor I/O used by contestants as IOI ( ACM ICPC like contest for school students ) does not require / emphasize fast I/O . Thanks for bringing a different approach to light . Probably some other contestants too might have used a sub-optimal algorithm to get AC . Cheers , Happy Coding .

1 Like

@vineetpaliwal: My post was not criticizing the fact that sub-optimal solutions got full points. For many problems it is very difficult to separate an O(N) algorithm from an O(N * log(N)) algorithm. And for lunch time contests it is probably even a good idea to allow such solutions to get full points. I only pointed out the segment tree solution because for some people it might be easier to grasp (as long as they are familiar with the segment tree data structure, which is rather well-known). A binary indexed tree (BIT) could also be used instead of a segment tree.

1 Like

Plz anyone help why i am getting WA …Here’s my solution in java…

import java.util.;
import java.io.
;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main
{
static class FastReader
{
BufferedReader br;
StringTokenizer st;

    public FastReader() 
    { 
        br = new BufferedReader(new
                 InputStreamReader(System.in)); 
    } 

    String next() 
    { 
        while (st == null || !st.hasMoreElements()) 
        { 
            try
            { 
                st = new StringTokenizer(br.readLine()); 
            } 
            catch (IOException  e) 
            { 
                e.printStackTrace(); 
            } 
        } 
        return st.nextToken(); 
    } 

    int nextInt() 
    { 
        return Integer.parseInt(next()); 
    } 

    long nextLong() 
    { 
        return Long.parseLong(next()); 
    } 

    double nextDouble() 
    { 
        return Double.parseDouble(next()); 
    } 

    String nextLine() 
    { 
        String str = ""; 
        try
        { 
            str = br.readLine(); 
        } 
        catch (IOException e) 
        { 
            e.printStackTrace(); 
        } 
        return str; 
    } 
}
public static void main(String args[]){
	FastReader sc = new FastReader();
    long n = sc.nextLong();
    long k = sc.nextLong();
    long[] arr = new long[(int)n];
    //System.out.println(n);
    for(int i = 0; i < n; i++)
    {
        arr[i] = sc.nextLong();
        //System.out.println(arr[i]);
    }
    LinkedList<Long> st = new LinkedList<Long>();
    LinkedList<Integer> ix = new LinkedList<Integer>();
    long cal = 1;
    for(int i = 0; i < n;  i++){
            if(i == 0){
                st.add(arr[i]);
                ix.add(i);
            }
            else{
                if(arr[i] >= st.peekLast()){
                    st.add(arr[i]);
                    ix.add(i);
                }
                else{
                    while(st.size() != 0 && arr[i] < st.peekLast()){
                        st.pollLast();
                        long x = ix.pollLast();
                        //System.out.println("x  " + x);
                        cal = cal*(i - x + 1);
                        cal = cal % 10000007;
                        //System.out.println(cal +" "+"cal");
                    }
                    st.add(arr[i]);
                    ix.add(i);
                    //System.out.println(st);
                }
                //System.out.println(st);
            }
    }
    System.out.println(cal % 10000007);
    
} 

}

@vineetpaliwal

Everything is correct except wrong modular arithmetic.
Corrected your solution and got an AC
See lines 76 and 98

import java.util.HashSet;
import java.util.Scanner;

class chefsinqueue {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);

    int n=sc.nextInt();
    int k=sc.nextInt();
    int mod=1000000007;
    int ar[]=new int[n];

    for(int i=0;i<n;i++){
        ar[i]=sc.nextInt();
    }

    int fear=1;
    int min=ar[n-1];
    for(int i=n-2;i>=0;i--){
        if(min<ar[i]){
            for(int j=i+1;j<n;j++){
                if(ar[i]>ar[j]){
                    fear*=(j-i+1)%mod;
                    break;
                }
            }
        }else{
            min=ar[i];
        }

    }

    System.out.println(fear);
    
}    

}

My solution is getting correct answers but I could not find where is the problem please help.

C++ code using Stack
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007

int main()
{
long n,k,i;
cin>>n>>k;
long a[n];
for(i=0;i<n;i++)
cin>>a[i];
long ff=1;
stackst;
st.push(n-1);
for(i=n-2;i>=0;i–)
{
while(!st.empty() && a[i]<=a[st.top()])
st.pop();
if(!st.empty())
{
int i2=st.top();
int i1=i;
ff=((ff%mod)*((i2%mod)-(i1%mod)+1))%mod;
}
st.push(i);
}
cout<<ff<<endl;
}

void solve()
{
ll n,k;
cin>>n>>k;
vector a(n+1),res(n+1,1);
vector check(n+1,false);
for(ll i=1;i<=n;i++){
cin>>a[i];
}
ll j=1,i=1,temp;
while(i+1<=n)
{
if(a[i]==1){
res[i]=1;
check[i]=true;
}
else{
if(a[i]>a[i+1]) {
check[i] = true;
res[i] = 2;
temp = i+1;
while (j <= i) {
if (!check[j]) {
res[j] = temp - j + 1;
check[j] = true;
}
j++;
}
}
}
i++;
}
ll final=1;
for (ll l = 1; l <=n ; ++l) {
final=(final*res[l])%MOD;
}
cout<<final<<endl;
}
I don"t understand why this isn’t working can someone help…