Heap

Heap data structure and priority queue problems involving min-heap, max-heap, and heap-based algorithms for efficient element retrieval.

Problems

Restaurant Rating

Problem Information

  • Source: CodeChef RRATING
  • Difficulty: Secret
  • Time Limit: 1000ms
  • Memory Limit: 256MB

Problem Statement

A restaurant receives reviews with ratings. After each review, they want to display the rating at the top 1/3 position (ceiling). For example, if there are 5 reviews, show the rating at position ceil(5/3) = 2 from top.

Operations:

  • “1 x”: Add a review with rating x
  • “2”: Query the rating at top 1/3 position (or “No reviews yet” if empty)

Input Format

  • Line 1: N (number of operations)
  • Next N lines: Operations as described above

Output Format

For each query (type 2), print the answer.

Example

Input:
5
1 5
1 7
1 3
2
1 9

Output:
7

After adding ratings 5, 7, 3: sorted = [7, 5, 3]. Position ceil(3/3) = 1. Top 1 rating is 7.

Solution

Approach

Use two heaps - one for top 1/3 ratings (min-heap to get minimum of top elements), another for candidates (max-heap). Keep balance as reviews are added.

Python Solution
from heapq import heappush, heappop, heapreplace

def solution():
    top_reviews = []      # min-heap for top 1/3
    candidate_reviews = []  # max-heap (negated) for remaining
    n = int(input())
    results = []
    num_reviews = 0

    for _ in range(n):
        command = input().strip()
        if command.startswith('1'):
            num_reviews += 1
            new_review = int(command.split()[1])
            if len(top_reviews) < num_reviews // 3:
                if not candidate_reviews or new_review > -candidate_reviews[0]:
                    heappush(top_reviews, new_review)
                else:
                    heappush(top_reviews, -heappop(candidate_reviews))
                    heappush(candidate_reviews, -new_review)
            else:
                if top_reviews and new_review > top_reviews[0]:
                    heappush(candidate_reviews, -heapreplace(top_reviews, new_review))
                else:
                    heappush(candidate_reviews, -new_review)
        else:
            results.append(top_reviews[0] if top_reviews else 'No reviews yet')

    print(*results, sep='\n')

solution()
Complexity Analysis
  • Time Complexity: O(N log N) for N operations with heap operations
  • Space Complexity: O(N) for storing all reviews

Monk and Multiplication

Problem Information

  • Source: Hackerearth
  • Difficulty: Secret
  • Time Limit: 2000ms
  • Memory Limit: 256MB

Problem Statement

Given an array of N integers added one by one, after each insertion output the product of the three largest numbers. If fewer than 3 numbers have been added, output -1.

Input Format

  • Line 1: N (number of elements)
  • Line 2: N space-separated integers

Output Format

N lines, each containing the product of 3 largest so far, or -1.

Example

Input:
5
1 2 3 4 5

Output:
-1
-1
6
24
60

After 1 element: -1. After 2: -1. After 3: 123=6. After 4: 234=24. After 5: 345=60.

Solution

Approach

Maintain a min-heap of size 3 with the largest elements. The heap root is always the smallest of the top 3.

Python Solution
from heapq import heapify, heapreplace
from math import prod

def solution():
    n = int(input())
    a = list(map(int, input().split()))

    if n < 3:
        print('\n'.join(['-1'] * n))
        return

    top3 = a[:3]
    heapify(top3)

    for i, val in enumerate(a):
        if i < 2:
            print(-1)
        elif i == 2:
            print(prod(top3))
        else:
            if val > top3[0]:
                heapreplace(top3, val)
            print(prod(top3))

solution()
Complexity Analysis
  • Time Complexity: O(N log 3) = O(N) for N insertions
  • Space Complexity: O(1) for the fixed-size heap of 3 elements

Problem Information

  • Source: Hackerearth
  • Difficulty: Secret
  • Time Limit: 2000ms
  • Memory Limit: 256MB

Problem Statement

Given N topics with current scores and engagement data (posts, likes, comments, shares), calculate new scores using:

new_score = posts*50 + likes*5 + comments*10 + shares*20

Find the top 5 trending topics based on the CHANGE in score (new - old). Ties are broken by higher topic ID.

Input Format

  • Line 1: N (number of topics)
  • Next N lines: topic_id current_score posts likes comments shares

Output Format

Top 5 topics with their new scores (highest change first).

Example

Input:
6
1 100 10 20 5 3
2 200 5 10 2 1
3 50 20 40 10 5
4 300 2 5 1 0
5 150 15 30 8 4
6 80 8 15 4 2

Output:
3 850
5 640
1 660
6 330
2 370

Topic 3 has highest change: new_score = 2050+405+1010+520 = 850, change = 850-50 = 800.

Solution

Approach

Use a min-heap of size 5 tracking top trending by score change. Custom comparison for the Topic class handles tie-breaking.

Python Solution
from heapq import heappush, heappop, heapreplace

class Topic:
    def __init__(self, topic_id, current_score, posts, likes, comments, shares):
        self.id = topic_id
        self.new_score = posts * 50 + likes * 5 + comments * 10 + shares * 20
        self.change_in_score = self.new_score - current_score

    def __lt__(self, other):
        if self.change_in_score != other.change_in_score:
            return self.change_in_score < other.change_in_score
        return self.id < other.id

def solution():
    n = int(input())
    top_trends = []

    for i in range(n):
        topic_id, z, p, l, c, s = map(int, input().split())
        topic = Topic(topic_id, z, p, l, c, s)

        if i < 5:
            heappush(top_trends, topic)
        elif top_trends[0] < topic:
            heapreplace(top_trends, topic)

    results = []
    while top_trends:
        topic = heappop(top_trends)
        results.append(f"{topic.id} {topic.new_score}")

    print(*reversed(results), sep='\n')

solution()
Complexity Analysis
  • Time Complexity: O(N log 5) = O(N) for processing N topics
  • Space Complexity: O(1) for fixed-size heap of 5 elements

QHEAP1

Problem Information

  • Source: Hackerrank
  • Difficulty: Secret
  • Time Limit: 4000ms
  • Memory Limit: 512MB

Problem Statement

Implement a min-heap that supports the following operations:

  • “1 v”: Add element v to the heap
  • “2 v”: Delete element v from the heap (v is guaranteed to exist)
  • “3”: Print the minimum element

Input Format

  • Line 1: Q (number of queries)
  • Next Q lines: Queries as described above

Output Format

For each type-3 query, print the minimum element.

Example

Input:
5
1 4
1 9
3
2 4
3

Output:
4
9

Insert 4, insert 9. Minimum is 4. Delete 4. Minimum is now 9.

Solution

Approach

Use a heap with lazy deletion. Track deleted elements separately and clean them when querying the minimum.

Python Solution
from heapq import heappush, heappop
from collections import Counter

def solution():
    q = int(input())
    heap = []
    deleted = Counter()

    for _ in range(q):
        query = input().split()
        if query[0] == '3':
            while deleted[heap[0]] > 0:
                deleted[heap[0]] -= 1
                heappop(heap)
            print(heap[0])
        elif query[0] == '1':
            heappush(heap, int(query[1]))
        else:
            deleted[int(query[1])] += 1

solution()
Complexity Analysis
  • Time Complexity: O(Q log Q) for Q operations
  • Space Complexity: O(Q) for heap and delete list

LAZYPROG - Lazy Programmer

Problem Information

  • Source: SPOJ
  • Difficulty: Secret
  • Time Limit: 368ms
  • Memory Limit: 1536MB

Problem Statement

A lazy programmer has N projects with deadlines. Each project i has:

  • a[i]: cost per unit time to speed up (dollars/hour)
  • b[i]: time needed to complete at normal speed (hours)
  • d[i]: deadline (hours from now)

He can pay to speed up any project. Find the minimum total cost to meet all deadlines.

Input Format

  • Line 1: T (test cases)
  • For each test case:
    • Line 1: N (number of projects)
    • Next N lines: a b d for each project

Output Format

Minimum cost (2 decimal places).

Example

Input:
1
2
1 2 2
2 1 3

Output:
0.50

Two projects: Project 1 costs 1$/hr to speed up, needs 2 hrs, deadline 2. Project 2 costs 2$/hr, needs 1 hr, deadline 3. Do P1 (2 hrs), then P2 (1 hr) = 3 hrs total. P2 finishes at hr 3, meeting deadline. But we need to speed up P1 by 0.5 hrs (cheaper at 1$/hr) to finish P2 by deadline 3. Cost = 0.5 * 1 = 0.50.

Solution

Approach

Sort by deadline, use heap to always speed up the cheapest project first. When a deadline is missed, take time from the project with lowest speedup cost.

Python Solution
from heapq import heappush, heappop

class Project:
    def __init__(self, a, b, d):
        self.a = a  # cost per unit time
        self.b = b  # time needed
        self.d = d  # deadline

    def __lt__(self, other):
        return self.a > other.a  # max-heap by cost (cheaper to speed up first)

def solution():
    t = int(input())

    for _ in range(t):
        total_cost = 0.0
        current_time = 0
        pq = []

        n = int(input())
        projects = [Project(*map(int, input().split())) for _ in range(n)]
        projects.sort(key=lambda x: x.d)

        for proj in projects:
            current_time += proj.b
            heappush(pq, proj)

            if current_time <= proj.d:
                continue

            while current_time > proj.d:
                cheapest = heappop(pq)
                time_over = current_time - proj.d
                if cheapest.b >= time_over:
                    cheapest.b -= time_over
                    total_cost += time_over / cheapest.a
                    current_time = proj.d
                    heappush(pq, cheapest)
                else:
                    total_cost += cheapest.b / cheapest.a
                    current_time -= cheapest.b

        print(f"{total_cost:.2f}")

solution()
Complexity Analysis
  • Time Complexity: O(N log N) for sorting and heap operations
  • Space Complexity: O(N) for storing projects

PRO - Promotion

Problem Information

  • Source: SPOJ
  • Difficulty: Secret
  • Time Limit: 1000ms
  • Memory Limit: 1536MB

Problem Statement

A supermarket runs a promotion over N days. Each day, some customers submit receipts. At the end of each day, the customer with the highest receipt wins prize equal to receipt value, and the lowest receipt customer wins prize equal to their receipt value (both are removed from future consideration).

Calculate total prize money: sum(max) - sum(min) over all days.

Input Format

  • Line 1: N (number of days)
  • Next N lines: k r1 r2 … rk (k receipts for that day)

Output Format

Total prize difference.

Example

Input:
2
3 1 2 3
2 1 2

Output:
4

Day 1: receipts [1,2,3]. Max=3 wins, Min=1 wins. Day 2: receipts [1,2]. Max=2 wins, Min=1 wins. Total = (3+2) - (1+1) = 4.

Solution

Approach

Use two heaps (min and max) with lazy deletion to track receipts efficiently.

Python Solution
from heapq import heappush, heappop
from collections import defaultdict

def solution():
    n = int(input())
    total_prizes = 0
    max_heap = []  # negated for max behavior
    min_heap = []

    deleted_from_max = defaultdict(int)
    deleted_from_min = defaultdict(int)

    for _ in range(n):
        line = list(map(int, input().split()))
        receipts = line[1:]

        for receipt in receipts:
            heappush(min_heap, receipt)
            heappush(max_heap, -receipt)

        if len(max_heap) >= 2:
            # Get max (skip deleted)
            while deleted_from_min[-max_heap[0]] > 0:
                deleted_from_min[-max_heap[0]] -= 1
                heappop(max_heap)
            from_max = heappop(max_heap)

            # Get min (skip deleted)
            while deleted_from_max[min_heap[0]] > 0:
                deleted_from_max[min_heap[0]] -= 1
                heappop(min_heap)
            from_min = heappop(min_heap)

            # Mark as deleted for the other heap
            deleted_from_max[from_max] += 1
            deleted_from_min[from_min] += 1

            total_prizes -= (from_max + from_min)

    print(total_prizes)

solution()
Complexity Analysis
  • Time Complexity: O(R log R) where R is total number of receipts
  • Space Complexity: O(R) for heaps and deletion arrays

I Can Guess the Data Structure!

Problem Information

  • Source: UVA 11995
  • Difficulty: Secret
  • Time Limit: 1000ms
  • Memory Limit: 256MB

Problem Statement

Given a sequence of operations (insert and extract), determine what data structure is being used: stack, queue, or priority queue (max-heap).

Operations:

  • “1 x”: Insert element x
  • “2 x”: Extract returns element x

Output:

  • “stack” if it matches stack behavior (LIFO)
  • “queue” if it matches queue behavior (FIFO)
  • “priority queue” if it matches max-heap behavior
  • “not sure” if multiple structures are possible
  • “impossible” if no structure matches

Input Format

Multiple test cases until EOF, each with N operations.

Output Format

One line per test case.

Example

Input:
6
1 1
1 2
1 3
2 1
2 2
2 3

Output:
queue

Insert 1, 2, 3 then extract 1, 2, 3. This is FIFO order, so it’s a queue.

Solution

Approach

Simulate all three structures simultaneously and check consistency with each extraction.

Python Solution
from heapq import heappush, heappop
from collections import deque
import sys

def solution():
    tokens = sys.stdin.read().split()[::-1]

    while tokens:
        n = int(tokens.pop())
        heap = []           # max-heap (negated)
        stack = []
        queue = deque()

        is_heap = is_stack = is_queue = True

        for _ in range(n):
            op, x = int(tokens.pop()), int(tokens.pop())

            if not any([is_heap, is_stack, is_queue]):
                continue

            if op == 1:
                if is_heap:
                    heappush(heap, -x)
                if is_stack:
                    stack.append(x)
                if is_queue:
                    queue.append(x)
            else:
                if is_heap:
                    if not heap or -heappop(heap) != x:
                        is_heap = False
                if is_stack:
                    if not stack or stack.pop() != x:
                        is_stack = False
                if is_queue:
                    if not queue or queue.popleft() != x:
                        is_queue = False

        matches = sum([is_heap, is_stack, is_queue])
        if matches > 1:
            print('not sure')
        elif matches == 0:
            print('impossible')
        elif is_stack:
            print('stack')
        elif is_queue:
            print('queue')
        else:
            print('priority queue')

solution()
Complexity Analysis
  • Time Complexity: O(N log N) per test case for heap operations
  • Space Complexity: O(N) for storing elements in each structure

Add All

Problem Information

  • Source: UVA 10954
  • Difficulty: Secret
  • Time Limit: 3000ms
  • Memory Limit: 256MB

Problem Statement

Given N numbers, you need to add them all together. Each addition operation costs the sum of the two numbers being added. Find the minimum total cost to combine all numbers into one.

Example: Numbers [1, 2, 3]

  • Add 1+2=3 (cost 3), then 3+3=6 (cost 6) = total 9

Input Format

  • Multiple test cases until N=0
  • Line 1: N
  • Line 2: N integers

Output Format

Minimum total cost for each test case.

Example

Input:
3
1 2 3
0

Output:
9

Numbers [1, 2, 3]. Add 1+2=3 (cost 3). Add 3+3=6 (cost 6). Total cost = 9.

Solution

Approach

Huffman-like algorithm - always add the two smallest numbers using a min-heap.

Python Solution
from heapq import heapify, heappop, heappush

def solution():
    while True:
        n = int(input())
        if n == 0:
            return

        nums = list(map(int, input().split()))
        heapify(nums)
        total_cost = 0

        while len(nums) > 1:
            first, second = heappop(nums), heappop(nums)
            combined = first + second
            total_cost += combined
            heappush(nums, combined)

        print(total_cost)

solution()
Complexity Analysis
  • Time Complexity: O(N log N) for N-1 heap operations
  • Space Complexity: O(N) for the heap