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

Pair Sums

Given an array, we define its value to be the value obtained by following these instructions: Write down all pairs of numbers from this array. Compute the product of each pair. Find the sum of all the products. For example, for a given array, for a given array [7,2 ,-1 ,2 ] Note that ( 7 , 2 ) is listed twice, one for each occurrence of 2. Given an array of integers, find the largest v

View Solution →

Lazy White Falcon

White Falcon just solved the data structure problem below using heavy-light decomposition. Can you help her find a new solution that doesn't require implementing any fancy techniques? There are 2 types of query operations that can be performed on a tree: 1 u x: Assign x as the value of node u. 2 u v: Print the sum of the node values in the unique path from node u to node v. Given a tree wi

View Solution →

Ticket to Ride

Simon received the board game Ticket to Ride as a birthday present. After playing it with his friends, he decides to come up with a strategy for the game. There are n cities on the map and n - 1 road plans. Each road plan consists of the following: Two cities which can be directly connected by a road. The length of the proposed road. The entire road plan is designed in such a way that if o

View Solution →

Heavy Light White Falcon

Our lazy white falcon finally decided to learn heavy-light decomposition. Her teacher gave an assignment for her to practice this new technique. Please help her by solving this problem. You are given a tree with N nodes and each node's value is initially 0. The problem asks you to operate the following two types of queries: "1 u x" assign x to the value of the node . "2 u v" print the maxim

View Solution →

Number Game on a Tree

Andy and Lily love playing games with numbers and trees. Today they have a tree consisting of n nodes and n -1 edges. Each edge i has an integer weight, wi. Before the game starts, Andy chooses an unordered pair of distinct nodes, ( u , v ), and uses all the edge weights present on the unique path from node u to node v to construct a list of numbers. For example, in the diagram below, Andy

View Solution →

Heavy Light 2 White Falcon

White Falcon was amazed by what she can do with heavy-light decomposition on trees. As a resut, she wants to improve her expertise on heavy-light decomposition. Her teacher gave her an another assignment which requires path updates. As always, White Falcon needs your help with the assignment. You are given a tree with N nodes and each node's value Vi is initially 0. Let's denote the path fr

View Solution →