Two disjoint intervals minimum sum - c++

Given a list of N intervals [a,b] cost c, find the minimum sum of 2 non-overlapping intervals. I have an algorithm in O(n^2) ( pastebin.com/kveAZTwv ) but i don t find the O(N log N).
The first value is the number of intervals. the other lines are : a,b,c where a is the beginning of the interval, b the end and c the cost.
example :
input :
3
0 10 1
1 2 2
9 12 2
output :
4

Here is the basic idea for an algorithm in O(n log n), I am sure it can be done more efficiently:
1) sort all intervals accoring to their endpoint, each endpoint is a potential splitpoint where intervals to the right and intervals to the left do not overlap
2) now scan through the sorted intervals and for each spiltpoint remember the minimum cost interval to the left.
3) sort all elements according to their startpoint
4) for each splitpoint memorize additionally the minimum cost interval to the right(having its startpoint after the splitpoint). This is also possible with a single scan from back to front of the sorted elements
5) for each splitpoint add the two corresponding cost and look for the minimum.
Sorry this is a bit informal since i am on mobile.

Related

Find the minimum time

The problem statement is ->
We want to scan N documents using two scanners. If S1 and S2 are the time taken by the scanner 1 and scanner 2 to scan a single document, find the minimum time required to scan all the N documents.
Example:-
S1 = 2, S2 = 4, N = 2
Output: 4
Explanation: Here we have two possibilities.
Either scan both documents in scanner 1 or
scan one document in each scanner.
In both the cases time required is 4.
I came up with a solution where we find all the combinations and insert them into the set. The minimum value will be the first element in the set.
The problem is the solution will have time complexity of O(n), but the accepted time complexity is O(logn).
I am thinking on the lines of binary search but can't come up with a solution.
What should be the approach?
If you could scan a fraction of a document, the fastest way would be to scan N*S2/(S1+S2) documents in scanner 1, and N*S1/(S1+S2) documents in scanner 2. And if these are not integers, you must round one of them up and one of them down, which gives you just two possibilities to check. This is O(1), not O(log n).
Well, I'm sharing the O(log n) approach. With binary search on ans / time, we could find the optimal time.
For binary search, we need upper bound & lower bound. Let's assume lower bound as 0. Now we need to find out the upper bound.
What will be the minimum time required if we scan all the documents in one scanner. It will be min (S1,S2) * N, right? Note: here we are not using other scanner which could scan documents while another one is busy. So min(S1,S2) * N will be our upper bound.
We've got our bounds,
Lower bound = 0
Upper bound = min(S1,S2) * N
Now do BS on time, take a mid & check how many documents can be scanned with scanner 1 scanner 2 within mid time. Whenever total scanned documents get >= N then mid could be ans
.
You can check BS from here - https://www.hackerearth.com/practice/algorithms/searching/binary-search/tutorial/

ACM ICPC - Exactly K bridges in Graph

I'm practicing for ACM ICPC and I came on this problem from 2017 ACM ICPC Arab Regionals:
First, let’s define an undirected connected labeled graph, it’s a graph with N nodes with a unique label
for each node and some edges, there’s no specific direction for each edge, also duplicate edges and edges
from a node to itself aren’t allowed, and from any node you can reach any other node.
A bridge in such graph is an edge that if we remove it, the graph will be disconnected (there will
exist nodes which aren’t reachable from each other).
In this problem you are given N and K, and your task is to count the number of different undirected
connected labeled graphs with exactly N nodes and K bridges. Since that number can be huge, print
it modulo M.
An edge is defined using the labels of the nodes it connects, for example we can say (X, Y ) is an
edge between X and Y , also (Y, X) is considered the same edge (since it’s undirected). Two graphs are
considered different, if there’s an edge which exists in one of them but not the other.
Input:
Your program will be tested on one or more test cases. The first line of the input will be a single integer
T (1 ≤ T ≤ 100) representing the number of test cases. Followed by T test cases.
Each test case will be just one line containing 3 integers separated by a space, N (1 ≤ N ≤ 50), K
(0 ≤ K < N) and M (1 ≤ M ≤ 10^9), which are the numbers described in the statement. It’s guaranteed that N will not be more than 25 in 95% of the test cases
Output:
For each test case, print a single line with the number of graphs as described above modulo M.
Sample Input:
4
3 2 10
3 0 10
6 3 10000
6 3 1000
Sample Output
3
1
2160
160
I tried to come up with some formula that would work for all N and K but I had no success. Can someone tell me what should I do to solve it, because I couldn't find any editorial? Thanks in advance

get the number of overlapping intervals, given two lists of intervals

I recently came across an interesting problem:
Given two lists of intervals, find the total number of overlapping intervals from the two lists.
Example
L1: ([1,2][2,3][4,5][6,7])
L2: ([1,5][2,3][4,7][5,7])
[1,5] overlaps [1,2] [2,3] [4,5]
[2,3] overlaps [1,2] [2,3]
[4,7] overlaps [4,5] [6,7]
[5,7] overlaps [4,5] [6,7]
total = 3+2+2+2 = 9
Obviously the brute force approach works, but it's too slow (I need something better than O(n^2)).
I also fond a similar problem here. But it's not exactly the same...
Any help is appreciated
Make two sorted lists with pairs (value; +1 or -1 for start and end of interval).
Two counters - Count1 and Count2 which show number of active intervals in the first and the second lists.
Walk through both lists in merge manner.
When you get pair from the first list with +1 - increment Count1
When you get pair from the first list with -1 - decrement Count1 and add Count2 to the result
The same for pairs from the second list
Pseudocode for the last stage
CntA = 0
CntB = 0
Res = 0
ia = 0
ib = 0
while (ia < A.Length) and (ib < B.Length)
if Compare(A[ia], B[ib]) <= 0
CntA = CntA + A[ia].Flag
if (A[ia].Flag < 0)
Res = Res + CntB
ia++
else
CntB = CntB + B[ib].Flag
if B[ib].Flag < 0
Res = Res + CntA
ib++
Subtle moment - comparison if Compare(A[ia], B[ib]) <= 0
We should here take into account also flags - to correctly treat situations when endpoints only touch like [1..2][2..3] (you consider this situation as intersection). So both sorting and merge comparator should take synthetic value like this: 3 * A[ia].Value - A[ia].Flag. With such comparing start of interval is treated before end of interval with the same coordinate.
P.S. Made quick test in Delphi. Works for given data set and pair of others.
Delphi code (ideone FPC doesn't compile it due to generics)
Try to look for sweep line algorithms, it will give you the fastest solution.
You can check short description at TopCoder site or watch video from Robert Sedgwick. These describe a bit more hard problem but should give you an approach how to solve yours.
Actually the main idea is to walk over sorted list of begins and ends of your segments each time updating the lists of segments in the special intersecting list.
For this task you will have two intersections lists for each original list respectively. At the start both intersection lists are empty. On coming over begin of the segment you add it to the appropriate intersection list and it obviously intersects all the segments in the other intersection list. When coming to an end of the segment just remove it from the intersection list.
This algorithm will give you O(n log(n)) speed and in worst case O(n) memory.
You may be able to use std::set_intersection in a loop over the second array to match it with each item in the first array. But I am not sure if the performance will match your requirements.
I recently stumbled upon the Interval Tree ADT when tackling a similar question - I suspect it'll be useful for you, whether you implement it or not.
It is basically a ternary tree, and I built it with nodes containing:
Left sub-tree containing intervals less than current node
Right sub-tree containing intervals more than current node
List of overlapping intervals
Interval value encompassing all overlapping intervals
After building the tree in O(n*log(n)), a query function - to check overlapping intervals - should be O(log(n) + m) where m is the number of overlapping intervals reported.
Note that on creation, sorting by end value in the interval and splitting the list should help keep things balanced.

Given the life time of different elephants, find the period when maximum number of elephants lived

I came across an interview question:
"Given life times of different elephants. Find the period when maximum number of elephants were alive." For example:
Input: [5, 10], [6, 15], [2, 7]
Output: [6,7] (3 elephants)
I wonder if this problem can be related to the Longest substring problem for 'n' number of strings, such that each string represents the continuous range of a time period.
For e.g:
[5,10] <=> 5 6 7 8 9 10
If not, what can be a good solution to this problem ? I want to code it in C++.
Any help will be appreciated.
For each elephant, create two events: elephant born, elephant died. Sort the events by date. Now walk through the events and just keep a running count of how many elephants are alive; each time you reach a new maximum, record the starting date, and each time you go down from the maximum record the ending date.
This solution doesn't depend on the dates being integers.
If i were you at the interview i would create a std::array with maximum age of the elephant and then increment elements number for each elephant like:
[5,10] << increment all elements from index 5 to 10 in array.
Then i would sort and find where is the biggest number.
There is possibility to use std::map like map<int,int> ( 1st - period, 2nd - number of elephants). It will be sorted by default.
Im wondering if you know any better solution?
This is similar to a program that checks to see if parenthesis are missing. It is also related to date range overlap. This subject is beaten to death on StackOverflow and elsewhere. Here it is:
Determine Whether Two Date Ranges Overlap
I have implemented this by placing all of the start/end ranged in one vector of structs (or classes) and then sorting them. Then you can run through the vector and detect transitions of the level of elephants. (Number of elephants -- funny way of stating the problem!)
From your Input I find that all the time period are overlapping then in that case the solution is simple
we have been given range as [start end]
so the answer will be maximum of all start and minimum of all end.
Just traverse over each time period and find the maximum of all start and mimumum of all end
Note : this solution is applicable when all the time periods over lap
In Your example
Maximum of all input = 6
Minimum of all output= 7
I will just make two arrays , one for the time elephants are born and one for the time elephants die . Sort both of the arrays.
Now keep a counter (initially at zero ) . Start traversing both the arrays and keep getting the smallest element from both of the arrays. If we get an element from start array then increment the counter , else decrement the counter. We can find the max value and the time easily by this method.

Similar elements from lists

With given N lists of M numbers in each list we have to find ONE element from each group such
every pair ai aj gives |ai-aj| as small as possible.
For example
we have 3 lists
{12,16,67,43}
{7,17,68,48}
{14,15,77,54}
And to minimize result we have to pick
number 16 from list 1
number 17 from list 2
number 15 from list 3
so
|16-17|=1
|16-15|=1
|17-15|=2
so our result is :2
How to solve it fastly? in N*M time ? or log something time
Chris
If you use a linear search, the complexity is O(N*M) for one match (i.e., for each element in set j, do a linear search for the most similar item from set i, and pick the smallest of those results.
If you sort each set first, you get to (at least) O(N log N)+O(M log M) for the sort, and O(M log N) for the searches (where N is the number of elements in set i, and M the number of elements in set j). If you walk through the two sets together you can probably reduce that to O(N + M) for the combined search.