Cloudy Day


Problem Statement :


Quibdó in Colombia is one among the cities that receive maximum rainfall in the world.

All year round, the city is covered in clouds. The city has many towns, located on a one-dimensional line. The positions and populations of each town on the number line are known to you. Every cloud covers all towns located at a certain distance from it. A town is said to be in darkness if there exists at least one cloud such that the town is within the cloud's range. Otherwise, it is said to be sunny.


The city council has determined that they have enough money to remove exactly one cloud using their latest technology. Thus they want to remove the cloud such that the fewest number of people are left in darkness after the cloud is removed. What is the maximum number of people that will be in a sunny town after removing exactly one cloud?

Note: If a town is not covered by any clouds, then it is already considered to be sunny, and the population of this town must also be included in the final answer.

Complete the function maximumPeople which takes four arrays representing the populations of each town, locations of the towns, locations of the clouds, and the extents of coverage of the clouds respectively, and returns the maximum number of people that will be in a sunny town after removing exactly one cloud.

Input Format

The first line of input contains a single integer , the number of towns.

The next line contains  space-separated integers . The  integer in this line denotes the population of the  town.

The next line contains  space-separated integers  denoting the location of the  town on the one-dimensional line.

The next line consists of a single integer  denoting the number of clouds covering the city.

The next line contains  space-separated integers  the  of which denotes the location of the  cloud on the coordinate axis.

The next line consists of  space-separated integers  denoting the range of the  cloud.

Note: The range of each cloud is computed according to its location, i.e., the  cloud is located at position  and it covers every town within a distance of  from it. In other words, the  cloud covers every town with location in the range



Output Format

Print a single integer denoting the maximum number of people that will be in a sunny town by removing exactly one cloud.



Solution :



title-img


                            Solution in C :

In  C :





#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
  int l;
  int r;
  long long zero;
  long long one;
  int off;
} node;
void build(int v,int tl,int tr);
void push(int v,int tl,int tr);
void range_update(int v,int tl,int tr,int pos1,int pos2);
long long sum(int v,int tl,int tr,int l,int r);
long long sum0(int v,int tl,int tr,int l,int r);
void sort_a2(int*a,int*b,int size);
void merge2(int*a,int*left_a,int*right_a,int*b,int*left_b,int*right_b,int left_size, int right_size);
int p[200000],l[200000],y[100000],r[100000];
node t[800000];

int main(){
  int n,m,i;
  long long max,temp;
  scanf("%d",&n);
  for(i=0;i<n;i++)
    scanf("%d",p+i);
  for(i=0;i<n;i++)
    scanf("%d",l+i);
  scanf("%d",&m);
  for(i=0;i<m;i++)
    scanf("%d",y+i);
  for(i=0;i<m;i++)
    scanf("%d",r+i);
  sort_a2(l,p,n);
  build(1,0,n-1);
  for(i=0;i<m;i++)
    range_update(1,0,n-1,y[i]-r[i],y[i]+r[i]);
  for(i=max=0;i<m;i++){
    temp=sum(1,0,n-1,y[i]-r[i],y[i]+r[i]);
    if(temp>max)
      max=temp;
  }
  printf("%lld",max+sum0(1,0,n-1,0,(1U<<31)-1));
  return 0;
}
void build(int v,int tl,int tr){
  int tm;
  if(tl==tr){
    t[v].l=t[v].r=l[tl];
    t[v].zero=p[tl];
    return;
  }
  tm=(tl+tr)/2;
  build(v*2,tl,tm);
  build(v*2+1,tm+1,tr);
  t[v].l=t[v*2].l;
  t[v].r=t[v*2+1].r;
  t[v].zero=t[v*2].zero+t[v*2+1].zero;
  return;
}
void push(int v,int tl,int tr){
  if(t[v].off==1){
    t[v].one=t[v].zero;
    t[v].zero=t[v].off=0;
    if(tl!=tr){
      t[v*2].off++;
      t[v*2+1].off++;
    }
  }
  else if(t[v].off>1){
    t[v].zero=t[v].one=t[v].off=0;
    if(tl!=tr){
      t[v*2].off+=2;
      t[v*2+1].off+=2;
    }
  }
  return;
}
void range_update(int v,int tl,int tr,int pos1,int pos2){
  int tm;
  if(pos2<t[v].l || pos1>t[v].r)
    return;
  push(v,tl,tr);
  if(pos1<=t[v].l && pos2>=t[v].r)
    t[v].off=1;
  else{
    tm=(tl+tr)/2;
    range_update(v*2,tl,tm,pos1,pos2);
    range_update(v*2+1,tm+1,tr,pos1,pos2);
    push(v*2,tl,tm);
    push(v*2+1,tm+1,tr);
    t[v].zero=t[v*2].zero+t[v*2+1].zero;
    t[v].one=t[v*2].one+t[v*2+1].one;
  }
  return;
}
long long sum(int v,int tl,int tr,int l,int r){
  int tm;
  if(r<t[v].l || l>t[v].r)
    return 0;
  push(v,tl,tr);
  tm=(tl+tr)/2;
  if(l<=t[v].l && r>=t[v].r)
    return t[v].one;
  else
    return sum(v*2,tl,tm,l,r)+sum(v*2+1,tm+1,tr,l,r);
}
long long sum0(int v,int tl,int tr,int l,int r){
  int tm;
  if(r<t[v].l || l>t[v].r)
    return 0;
  push(v,tl,tr);
  tm=(tl+tr)/2;
  if(l<=t[v].l && r>=t[v].r)
    return t[v].zero;
  else
    return sum0(v*2,tl,tm,l,r)+sum0(v*2+1,tm+1,tr,l,r);
}
void sort_a2(int*a,int*b,int size){
  if (size < 2)
    return;
  int m = (size+1)/2,i;
  int*left_a,*left_b,*right_a,*right_b;
  left_a=(int*)malloc(m*sizeof(int));
  right_a=(int*)malloc((size-m)*sizeof(int));
  left_b=(int*)malloc(m*sizeof(int));
  right_b=(int*)malloc((size-m)*sizeof(int));
  for(i=0;i<m;i++){
    left_a[i]=a[i];
    left_b[i]=b[i];
  }
  for(i=0;i<size-m;i++){
    right_a[i]=a[i+m];
    right_b[i]=b[i+m];
  }
  sort_a2(left_a,left_b,m);
  sort_a2(right_a,right_b,size-m);
  merge2(a,left_a,right_a,b,left_b,right_b,m,size-m);
  free(left_a);
  free(right_a);
  free(left_b);
  free(right_b);
  return;
}
void merge2(int*a,int*left_a,int*right_a,int*b,int*left_b,int*right_b,int left_size, int right_size){
  int i = 0, j = 0;
  while (i < left_size|| j < right_size) {
    if (i == left_size) {
      a[i+j] = right_a[j];
      b[i+j] = right_b[j];
      j++;
    } else if (j == right_size) {
      a[i+j] = left_a[i];
      b[i+j] = left_b[i];
      i++;
    } else if (left_a[i] <= right_a[j]) {
      a[i+j] = left_a[i];
      b[i+j] = left_b[i];
      i++;
    } else {
      a[i+j] = right_a[j];
      b[i+j] = right_b[j];
      j++;
    }
  }
  return;
}
                        


                        Solution in C++ :

In  C++  :







#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair <int, int> ii;

const int Maxn = 200005;

vector <ii> seq;
int delt[Maxn];
ll sum[Maxn];

ll maximumPeople(vector <long> p, vector <long> x, vector <long> y, vector <long> r) {
    for (int i = 0; i < p.size(); i++)
        seq.push_back(ii(x[i], p[i]));
    sort(seq.begin(), seq.end());
    for (int i = 0; i < y.size(); i++) {
        int lef = y[i] - r[i], rig = y[i] + r[i];
        int ind1 = lower_bound(seq.begin(), seq.end(), ii(lef, 0)) - seq.begin();
        int ind2 = lower_bound(seq.begin(), seq.end(), ii(rig + 1, 0)) - seq.begin();
        delt[ind1]++; delt[ind2]--;
    }
    ll res = 0;
    int cur = 0;
    for (int i = 0; i < seq.size(); i++) {
        cur += delt[i];
        if (cur == 0) res += seq[i].second;
        else if (cur == 1) sum[i] = seq[i].second;
        if (i) sum[i] += sum[i - 1];
    }
    ll add = res;
    for (int i = 0; i < y.size(); i++) {
        int lef = y[i] - r[i], rig = y[i] + r[i];
        int ind1 = lower_bound(seq.begin(), seq.end(), ii(lef, 0)) - seq.begin();
        int ind2 = lower_bound(seq.begin(), seq.end(), ii(rig + 1, 0)) - seq.begin();
        if (ind2 > 0) {
            ll got = sum[ind2 - 1];
            if (ind1 > 0) got -= sum[ind1 - 1];
            res = max(res, add + got);
        }
    }
    return res;
}

int main() {
    int n;
    cin >> n;
    vector<long> p(n);
    for(int p_i = 0; p_i < n; p_i++){
       cin >> p[p_i];
    }
    vector<long> x(n);
    for(int x_i = 0; x_i < n; x_i++){
       cin >> x[x_i];
    }
    int m;
    cin >> m;
    vector<long> y(m);
    for(int y_i = 0; y_i < m; y_i++){
       cin >> y[y_i];
    }
    vector<long> r(m);
    for(int r_i = 0; r_i < m; r_i++){
       cin >> r[r_i];
    }
    ll result = maximumPeople(p, x, y, r);
    cout << result << endl;
    return 0;
}
                    


                        Solution in Java :

In  Java :








import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Scanner;

public class Solution {

	static long maximumPeople(long[] p, long[] x, long[] y, long[] r) {
		long free = 0;
		long[] sum = new long[y.length];
		ArrayList<Event> al = new ArrayList<>();
		HashSet<Integer> clouds = new HashSet<>();
		for (int i = 0; i < p.length; i++) {
			al.add(new Event(1, x[i], p[i], i));
		}

		for (int i = 0; i < y.length; i++) {
			al.add(new Event(0, y[i] - r[i], -1, i));
			al.add(new Event(2, y[i] + r[i], -1, i));
		}

		Collections.sort(al);

		for (Event e : al) {
			if (e.type == 0) {
				clouds.add(e.index);
			} else if (e.type == 1) {
				if (clouds.isEmpty()) {
					free += e.pr;
				} else {
					if (clouds.size() == 1) {
						for (int q : clouds) {
							sum[q] += e.pr;
						}
					}
				}
			} else {
				clouds.remove(e.index);
			}
		}

		long mx = 0;
		for (long i : sum) {
			mx = Math.max(mx, i);
		}
		return free + mx;
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		long[] p = new long[n];
		for (int p_i = 0; p_i < n; p_i++) {
			p[p_i] = in.nextLong();
		}
		long[] x = new long[n];
		for (int x_i = 0; x_i < n; x_i++) {
			x[x_i] = in.nextLong();
		}
		int m = in.nextInt();
		long[] y = new long[m];
		for (int y_i = 0; y_i < m; y_i++) {
			y[y_i] = in.nextLong();
		}
		long[] r = new long[m];
		for (int r_i = 0; r_i < m; r_i++) {
			r[r_i] = in.nextLong();
		}
		long result = maximumPeople(p, x, y, r);
		System.out.println(result);
		in.close();
	}
}

class Event implements Comparable<Event> {
	int type;
	long x;
	long pr;
	int index;

	public Event(int type, long x, long pr, int index) {
		super();
		this.type = type;
		this.x = x;
		this.pr = pr;
		this.index = index;
	}

	@Override
	public int compareTo(Event e) {
		if (x != e.x) {
			return Long.compare(x, e.x);
		}
		return Integer.compare(type, e.type);
	}

}
                    


                        Solution in Python : 
                            
In  Python3 :








from collections import defaultdict


def maximumPeople(towns, cloud_start, cloud_end):
    towns = sorted(towns)
    cloud_start = sorted(cloud_start)
    cloud_end = sorted(cloud_end)

    cloud_start_i = 0
    cloud_end_i = 0
    clouds = set()

    d = defaultdict(int)
    free = 0
    for town_i in range(len(towns)):
        town_x = towns[town_i][0]
        while cloud_start_i < len(cloud_start) and cloud_start[cloud_start_i][0] <= town_x:
            clouds.add(cloud_start[cloud_start_i][1])
            cloud_start_i += 1
        while cloud_end_i < len(cloud_end) and cloud_end[cloud_end_i][0] < town_x:
            clouds.remove(cloud_end[cloud_end_i][1])
            cloud_end_i += 1
        if len(clouds) == 1:
            towns[town_i][2] = list(clouds)[0]
            d[list(clouds)[0]] += towns[town_i][1]
        elif len(clouds) == 0:
            free += towns[town_i][1]

    return max(d.values(), default=0) + free


def main():
    n = int(input().strip())
    p = [int(x) for x in input().strip().split()]
    x = [int(x) for x in input().strip().split()]
    towns = [[xi, pi, -1] for xi, pi in zip(x, p)]
    m = int(input().strip())
    y = [int(x) for x in input().strip().split()]
    r = [int(x) for x in input().strip().split()]
    cloud_start = [[y[i]-r[i], i] for i in range(m)]
    cloud_end = [[y[i]+r[i], i] for i in range(m)]
    result = maximumPeople(towns, cloud_start, cloud_end)
    print(result)

if __name__ == "__main__":
    main()
                    


View More Similar Problems

Sparse Arrays

There is a collection of input strings and a collection of query strings. For each query string, determine how many times it occurs in the list of input strings. Return an array of the results. Example: strings=['ab', 'ab', 'abc'] queries=['ab', 'abc', 'bc'] There are instances of 'ab', 1 of 'abc' and 0 of 'bc'. For each query, add an element to the return array, results=[2,1,0]. Fun

View Solution →

Array Manipulation

Starting with a 1-indexed array of zeros and a list of operations, for each operation add a value to each of the array element between two given indices, inclusive. Once all operations have been performed, return the maximum value in the array. Example: n=10 queries=[[1,5,3], [4,8,7], [6,9,1]] Queries are interpreted as follows: a b k 1 5 3 4 8 7 6 9 1 Add the valu

View Solution →

Print the Elements of a Linked List

This is an to practice traversing a linked list. Given a pointer to the head node of a linked list, print each node's data element, one per line. If the head pointer is null (indicating the list is empty), there is nothing to print. Function Description: Complete the printLinkedList function in the editor below. printLinkedList has the following parameter(s): 1.SinglyLinkedListNode

View Solution →

Insert a Node at the Tail of a Linked List

You are given the pointer to the head node of a linked list and an integer to add to the list. Create a new node with the given integer. Insert this node at the tail of the linked list and return the head node of the linked list formed after inserting this new node. The given head pointer may be null, meaning that the initial list is empty. Input Format: You have to complete the SinglyLink

View Solution →

Insert a Node at the head of a Linked List

Given a pointer to the head of a linked list, insert a new node before the head. The next value in the new node should point to head and the data value should be replaced with a given value. Return a reference to the new head of the list. The head pointer given may be null meaning that the initial list is empty. Function Description: Complete the function insertNodeAtHead in the editor below

View Solution →

Insert a node at a specific position in a linked list

Given the pointer to the head node of a linked list and an integer to insert at a certain position, create a new node with the given integer as its data attribute, insert this node at the desired position and return the head node. A position of 0 indicates head, a position of 1 indicates one node away from the head and so on. The head pointer given may be null meaning that the initial list is e

View Solution →