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 :
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
Truck Tour
Suppose there is a circle. There are N petrol pumps on that circle. Petrol pumps are numbered 0 to (N-1) (both inclusive). You have two pieces of information corresponding to each of the petrol pump: (1) the amount of petrol that particular petrol pump will give, and (2) the distance from that petrol pump to the next petrol pump. Initially, you have a tank of infinite capacity carrying no petr
View Solution →Queries with Fixed Length
Consider an -integer sequence, . We perform a query on by using an integer, , to calculate the result of the following expression: In other words, if we let , then you need to calculate . Given and queries, return a list of answers to each query. Example The first query uses all of the subarrays of length : . The maxima of the subarrays are . The minimum of these is . The secon
View Solution →QHEAP1
This question is designed to help you get a better understanding of basic heap operations. You will be given queries of types: " 1 v " - Add an element to the heap. " 2 v " - Delete the element from the heap. "3" - Print the minimum of all the elements in the heap. NOTE: It is guaranteed that the element to be deleted will be there in the heap. Also, at any instant, only distinct element
View Solution →Jesse and Cookies
Jesse loves cookies. He wants the sweetness of all his cookies to be greater than value K. To do this, Jesse repeatedly mixes two cookies with the least sweetness. He creates a special combined cookie with: sweetness Least sweet cookie 2nd least sweet cookie). He repeats this procedure until all the cookies in his collection have a sweetness > = K. You are given Jesse's cookies. Print t
View Solution →Find the Running Median
The median of a set of integers is the midpoint value of the data set for which an equal number of integers are less than and greater than the value. To find the median, you must first sort your set of integers in non-decreasing order, then: If your set contains an odd number of elements, the median is the middle element of the sorted sample. In the sorted set { 1, 2, 3 } , 2 is the median.
View Solution →Minimum Average Waiting Time
Tieu owns a pizza restaurant and he manages it in his own way. While in a normal restaurant, a customer is served by following the first-come, first-served rule, Tieu simply minimizes the average waiting time of his customers. So he gets to decide who is served first, regardless of how sooner or later a person comes. Different kinds of pizzas take different amounts of time to cook. Also, once h
View Solution →