CSES Solutions - Traffic Lights
Last Updated :
22 Mar, 2024
There is a street of length X whose positions are numbered 0,1 ... X. Initially there are no traffic lights, but N sets of traffic lights are added to the street one after another denoted by P[]. Your task is to calculate the length of the longest passage without traffic lights after each addition.
Examples:
Input: X = 8, N = 3, P[] = {3, 6, 2}
Output: 5 3 3
Explanation: After the first traffic light is added at position 3, we have two passages: 0 to 3 and 3 to 8. So, the maximum length will be 8 - 3 = 5. After the second traffic light is added at position 6, we have three passages: 0 to 3, 3 to 6 and 6 to 8. So, the maximum length will be 6 - 3 = 3. After the third traffic light is added at position 2, we have 4 passages: 0 to 2, 2 to 3, 3 to 6 and 6 to 8. So, the maximum length of passage will be 6 - 3 = 3.
Input: X = 7, N = 2, P[] = {2, 3}
Output: 5 4
Explanation: After the first traffic light is added at position 2, we have two passages: 0 to 2 and 2 to 7. So, the maximum length will be 7 - 2 = 5. After the second traffic light is added at position 3, we have three passages: 0 to 2, 2 to 3 and 3 to 7. So, the maximum length will be 7 - 3 = 4.
Approach: To solve the problem, follow the below idea:
The problem can be solved using set of pairs to store the starting and ending of all ranges and multiset to store the lengths of all ranges. Initially, we push the range (0, X) to the set and store the length X to the multiset. For every traffic light at position P, we find the range [L, R] in which position P lies and remove [L, R] and insert [L, P] and [P, R]. Also, we remove the length of range [L, R] from multiset and insert the lengths of [L, P] and [P, R]. We can find the length of longest passage from the multiset.
Step-by-step algorithm:
- Declare a set ranges to store the starting and ending point of ranges.
- Declare a multiset range_lengths to store the lengths of the ranges.
- Iterate through all the points and find the range[L, R] in which the point at position X lies.
- Break the ranges into two parts: L to X and X to R and push their lengths into the range lengths.
- Also remove the range [L, R] from the set and its length from the multiset.
- As multiset has elements sorted in ascending order, we can print the last element of the multiset as the answer.
Below is the implementation of the algorithm:
C++
#include <bits/stdc++.h>
#define ll long long
using namespace std;
void solve(ll X, ll N, ll* P)
{
// to store ranges
set<pair<int, int> > ranges;
ranges.insert({ 0, X });
// to store range lengths
multiset<ll> range_lengths;
range_lengths.insert(X);
for (int i = 0; i < N; i++) {
ll pos = P[i];
// find the range in which pos lies
auto it = ranges.upper_bound({ pos, 0 });
it--;
ll start = it->first;
ll end = it->second;
// Remove range [start, end] from ranges
ranges.erase(it);
// Remove length of range [start, end] from the
// range_lengths
range_lengths.erase(
range_lengths.find(end - start));
// Insert the new ranges
ranges.insert({ start, pos });
ranges.insert({ pos, end });
range_lengths.insert(pos - start);
range_lengths.insert(end - pos);
// Print the last element of multiset as the answer
cout << *range_lengths.rbegin() << "\n";
}
}
// Drive Code
int main()
{
ll X = 8, N = 3, P[] = { 3, 6, 2 };
solve(X, N, P);
return 0;
}
Java
import java.util.TreeMap;
import java.util.TreeSet;
public class Main {
public static void solve(long X, int N, long[] P)
{
// to store ranges
TreeSet<Pair<Long, Long> > ranges = new TreeSet<>();
ranges.add(new Pair<>(0L, X));
// to store range lengths
TreeMap<Long, Integer> range_lengths
= new TreeMap<>();
range_lengths.put(X, 1);
for (int i = 0; i < N; i++) {
long pos = P[i];
// find the range in which pos lies
Pair<Long, Long> it = ranges.floor(
new Pair<>(pos, Long.MAX_VALUE));
long start = it.first;
long end = it.second;
// Remove range [start, end] from ranges
ranges.remove(it);
// Remove length of range [start, end] from the
// range_lengths
int length = range_lengths.get(end - start);
if (length == 1) {
range_lengths.remove(end - start);
}
else {
range_lengths.put(end - start, length - 1);
}
// Insert the new ranges
ranges.add(new Pair<>(start, pos));
ranges.add(new Pair<>(pos, end));
range_lengths.put(
pos - start,
range_lengths.getOrDefault(pos - start, 0)
+ 1);
range_lengths.put(
end - pos,
range_lengths.getOrDefault(end - pos, 0)
+ 1);
// Print the last element of map as the answer
System.out.println(range_lengths.lastKey());
}
}
public static void main(String[] args)
{
long X = 8;
int N = 3;
long[] P = { 3, 6, 2 };
solve(X, N, P);
}
static class Pair<K extends Comparable<K>, V
extends Comparable<V> >
implements Comparable<Pair<K, V> > {
K first;
V second;
public Pair(K first, V second)
{
this.first = first;
this.second = second;
}
@Override public int compareTo(Pair<K, V> other)
{
int cmp = this.first.compareTo(other.first);
if (cmp != 0)
return cmp;
return this.second.compareTo(other.second);
}
}
}
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class RangeSolver
{
public static void Solve(int X, int N, int[] P)
{
// to store ranges
List<Tuple<int, int>> ranges = new List<Tuple<int, int>>();
ranges.Add(Tuple.Create(0, X));
// to store range lengths
Dictionary<int, int> rangeLengths = new Dictionary<int, int>();
rangeLengths[X] = 1;
for (int i = 0; i < N; i++)
{
int pos = P[i];
// find the range in which pos lies
Tuple<int, int> it = null;
foreach (var r in ranges)
{
if (r.Item1 <= pos && pos <= r.Item2)
{
it = r;
break;
}
}
Tuple<int, int> range = it ?? throw new InvalidOperationException("Range not found");
int start = range.Item1;
int end = range.Item2;
// Remove range [start, end] from ranges
ranges.Remove(range);
// Remove length of range [start, end] from the rangeLengths
int length = rangeLengths[end - start];
if (length == 1)
{
rangeLengths.Remove(end - start);
}
else
{
rangeLengths[end - start] = length - 1;
}
// Insert the new ranges
ranges.Add(Tuple.Create(start, pos));
ranges.Add(Tuple.Create(pos, end));
if (rangeLengths.ContainsKey(pos - start))
rangeLengths[pos - start] += 1;
else
rangeLengths[pos - start] = 1;
if (rangeLengths.ContainsKey(end - pos))
rangeLengths[end - pos] += 1;
else
rangeLengths[end - pos] = 1;
// Print the last element of map as the answer
Console.WriteLine(rangeLengths.Keys.Max());
}
}
// Drive Code
public static void Main(string[] args)
{
int X = 8, N = 3;
int[] P = { 3, 6, 2 };
Solve(X, N, P);
}
}
JavaScript
function solve(X, N, P) {
// Define a set to store ranges
let ranges = new Set();
ranges.add([0, X]);
// Define a map to store range lengths
let rangeLengths = new Map();
rangeLengths.set(X, 1);
for (let i = 0; i < N; i++) {
let pos = P[i];
// Find the range in which pos lies
let it = Array.from(ranges).find(([start, end]) => pos >= start && pos < end);
let [start, end] = it;
// Remove range [start, end] from ranges
ranges.delete(it);
// Remove length of range [start, end] from the rangeLengths
let length = end - start;
let count = rangeLengths.get(length);
if (count === 1) {
rangeLengths.delete(length);
} else {
rangeLengths.set(length, count - 1);
}
// Insert the new ranges
ranges.add([start, pos]);
ranges.add([pos, end]);
// Update rangeLengths
let leftLength = pos - start;
let rightLength = end - pos;
rangeLengths.set(leftLength, (rangeLengths.get(leftLength) || 0) + 1);
rangeLengths.set(rightLength, (rangeLengths.get(rightLength) || 0) + 1);
// Print the last element of map as the answer
console.log(Math.max(...Array.from(rangeLengths.keys())));
}
}
// Main function
function main() {
let X = 8;
let N = 3;
let P = [3, 6, 2];
solve(X, N, P);
}
// Run the main function
main();
Python3
# Python program for the above approach
from collections import defaultdict
def solve(X, N, P):
# to store ranges
ranges = [(0, X)]
# to store range lengths
range_lengths = defaultdict(int)
range_lengths[X] = 1
for i in range(N):
pos = P[i]
# find the range in which pos lies
it = None
for r in ranges:
if r[0] <= pos <= r[1]:
it = r
break
start, end = it
# Remove range [start, end] from ranges
ranges.remove(it)
# Remove length of range [start, end] from the range_lengths
length = range_lengths[end - start]
if length == 1:
del range_lengths[end - start]
else:
range_lengths[end - start] = length - 1
# Insert the new ranges
ranges.append((start, pos))
ranges.append((pos, end))
range_lengths[pos - start] += 1
range_lengths[end - pos] += 1
# Print the last element of map as the answer
print(max(range_lengths.keys()))
X = 8
N = 3
P = [3, 6, 2]
solve(X, N, P)
# This code is contributed by Susobhan Akhuli
Time Complexity: O(N * logN), where N is the number of traffic lights.
Auxiliary Space: O(N)
Similar Reads
CSES Problem Set Solutions
In this article, we have compiled comprehensive, high-quality tutorials on the CSES Problem Set Solutions to assist you in understanding the problem set for learning algorithmic programming. What is CSES Problem Set?CSES Problem Set is a collection of competitive programming tasks hosted on the CSES
8 min read
How to Check Traffic in Google Maps?
Google Maps is a powerful tool for navigation and trip planning, offering real-time traffic updates and detailed traffic conditions. Knowing how to check traffic in Google Maps can help you avoid delays, choose the best routes, and ensure a smoother travel experience. This guide will walk you throug
4 min read
Traffic Light Control Project using Arduino
Arduino is an open-source electronics platform based on easy-to-use hardware and software. Arduino boards can read digital & analog inputs from the sensors. With Arduino, you can write and upload computer code to a physical programmable circuit board (commonly called a microcontroller which is A
3 min read
Bulma Notification Light colors
Bulma is a free, open-source CSS framework based on Flexbox. It is component-rich, compatible, and well documented. It is highly responsive in nature. It uses classes to implement its design. The notification is a simple colored block that draws the attention of the user to something. It can be used
4 min read
Braille System - Light | Class 8 Physics
Braille is a system developed by Louis Braille in 1824 to help visually challenged people. It is a code by which languages such as English, French, Spanish, etc can be written and read by people that have defects in there eyes. This code consists of raised dots, that can be read with fingers by blin
3 min read
Counting City Trips with K Stops
Given n cities connected by (n-1) roads, each specified by [a, b, type], denoting a connection between cities a and b of a certain 'type' (0 for normal roads, 1 for highways). The task is to count the number of trips satisfying two conditions: The trip must include travel via a highway at least once
9 min read
What is Ambient Lighting?
When it comes to computer graphics, lighting is just as important as the object itself. After all, without the proper lighting, an object can appear dull, bland, and unappealing. One of the most important elements of lighting is ambient lighting, which is a type of lighting that helps create a reali
5 min read
HTML <blink> Tag
The HTML <blink> tag was used to create blinking text that flashes slowly. It is now obsolete and unsupported in modern browsers, as it was never standardized. Instead, CSS and JavaScript are recommended for similar effects, although blinking text is generally discouraged for accessibility rea
2 min read
Task Scheduler Using HTML, CSS and JS
In this article, we will create a Task Scheduler web application using HTML, CSS and JavaScript. This is an application which can store tasks provided by user and classified them as low priority, middle priority, and high priority. User also can provide a deadline for the task. User also can mark do
3 min read
Introduction of Light Fidelity (Li-Fi)
Light Fidelity (Li-Fi) is VLC, visible light communication technology developed by research team at University of Edinburgh, including Professor Haas. Professor Harald Haas authored term. Light Fidelity is modern wireless communication technology that empowers remote transmission of data using LED l
5 min read