The 14th Lanqiao Cup Provincial Competition Python Group B Question D - Pipeline (AC)

1. Pipeline

1. Problem description

There is a length of len \text{len}The horizontal pipe of len is divided into len \text{len}len segments, each segment has a switchable valve and a sensor for detecting water flow in the center.

Initially the pipe is empty and located at L i L_iLiThe valve will be at S i S_iSiLeave it open at all times and keep water flowing into the pipe.

For L i L_iLivalve, the water it flows into is at T i T_iTi( T i ≥ S i T_i \geq S_iTiSi) moment will make the starting point from L i − ( T i − S i ) L_i - (T_i - S_i)Li(TiSi) stageL i + ( T i − S i ) L_i + (T_i - S_i)Li+(TiSi) segment sensor detects water flow.

Find the earliest time at which the sensor in the middle of each section of the pipe detects water flow.

2. Input format

The first line of input contains two integers n, len n,\text{len}n,len , separated by a space, respectively represent the number of valves that will be opened and the length of the pipe.

nextnn _Each line of n lines contains two integers L i , S i L_i,S_iLi,Si, separated by a space, indicates that it is located at L i L_iLiThe valve in the center of the pipeline segment will be at S i S_iSiAlways open.

3. Output format

One line of output contains an integer representing the answer.

4. Sample input

3 10
1 1
6 5
10 2

5. Sample output

5

6. Evaluation use case scale and conventions

for 30 3030 % of evaluation cases,n ≤ 200 n \leq 200n200 S i , len ≤ 3000 S_i, \text{len} \leq 3000 Si,len3000

for 70 7070 % of evaluation cases,n ≤ 5000 n \leq 5000n5000 S i , len ≤ 1 0 5 S_i, \text{len} \leq 10^5 Si,len105

For all evaluation cases, 1 ≤ n ≤ 1 0 5 ​ 1 \leq n \leq 10^51n105 1 ≤ S i , len ≤ 1 0 9 ​ 1 \leq S_i,\text{len} \leq 10^9​ 1Si,len109 1 ≤ L i ≤ len​ 1 \leq L_i \leq \text{len}​ 1Lilen L i − 1 < L i ​ L_{i-1} < L_i​ Li1<Li

2. Problem-solving ideas

For a time point xxx , if all sensors can detect water flow at this time, then when the time point is greater thanxxWhen x , it must also be ensured that all sensors can detect water flow. The question requires us to find the smallest time point that meets the conditions. Because the answer is bipartite, we can think of a dichotomous answer.

After having the dichotomous idea, the problem is converted to a certain time point xxx , how do we judge that all sensors can detect water flow at this time? Think carefully, when the time is determined, for a person located inai a_iaiAnd the opening time is S i ( S i ≤ x ) S_i(S_i \leq x)Si(Six ) valve, its water flow is actually a coverage interval[ ai − ( x − S i ) , ai + ( x − S i ) ] [a_i-(x-S_i),a_i+(x-S_i)][ai(xSi),ai+(xSi)] line segment.

We can take all S i ≤ x S_i \leq xSiThe valves of x are all converted, and what is actually obtained is several line segments. Determining whether all sensors can detect water flow is equivalent to determining whether these several line segments can cover the interval[1, len] [1,\text{len}][1,len ] , the problem is then transformed into an interval coverage problem.

Interval coverage is a classic problem. We can sort these intervals by their left endpoint. Next, we check whether these intervals cover the entire pipeline. If the left endpoint of the first interval is greater than 1 11 , then it means that the beginning of the pipeline is not covered and returns directlyfalse. Otherwise we set a variablerrr represents the farthest reachable distance,rrThe initial value of r is the right endpoint of the first interval. We then check whether other intervals are consistent withrrr adjacent or overlapping. If the current interval andrrr is adjacent or overlapping, we add the right endpoint of the current interval andrr takes the maximum value. Finally ifr ≥ len r \geq \text{len}rlen means that all intervals are successfully covered, otherwise it means that it is not.

Let’s go back and consider how to write dichotomy. Let lll is the lower bound of the answer,rrr is the upper bound of the answer. If the time point obtained by dichotomy ismid \text{mid}mid is eligible because it is greater thanmid \text{mid}The time point of mid must also meet the conditions, so updater = mid r=\text{mid}r=mid , otherwise updatel = mid+1 l=\text{mid+1}l=mid+1 . We repeat this process until the left and right endpoints of the search range are equal, at which point the earliest time is found. Of coursel , rl,rl,We also need to think about the initial value of r , lll is obviously1 11 , whilerrrWe need to consider the limit situation, that is, there is only one leftmost or rightmost valve that opens at the latest time point. Obviously, the time required at this time is2 × 1 0 9 2 \times 10^92×109 , sorrThe initial value of r is 2 × 1 0 9 2 \times 10^92×109

Time complexity: O ( n log ⁡ n 2 ) O(n\log n^2)O ( nlogn2)

3. AC_Code

  • C++
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define sz(s) ((int)s.size())

int n, m;
int main()
{
    
    
	ios_base :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	vector<int> a(n), s(n);
	for (int i = 0; i < n; ++i) {
    
    
		cin >> a[i] >> s[i];
	}
	auto check = [&](LL t) {
    
    
		std::vector<pair<LL, LL>> v;
		for (int i = 0; i < n; ++i) {
    
    
			if (t >= s[i]) v.push_back({
    
    a[i] - (t - s[i]), a[i] + (t - s[i])});
		}
		sort(v.begin(), v.end());
		if (sz(v) == 0 || v[0].first > 1) return false;
		LL r = v[0].second;
		for (int i = 1; i < sz(v); ++i) {
    
    
			if (v[i].first <= r + 1) r = max(r, v[i].second);
			else break;
		}
		return r >= m;
	};
	LL l = 1, r = 2e9;
	while (l < r) {
    
    
		LL mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	cout << r << '\n';
	return 0;
}
  • Java
import java.util.*;

public class Main {
    
    
    static int n, m;

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        int[] a = new int[n];
        int[] s = new int[n];
        for (int i = 0; i < n; ++i) {
    
    
            a[i] = sc.nextInt();
            s[i] = sc.nextInt();
        }
        long l = 1, r = 2_000_000_000;
        while (l < r) {
    
    
            long mid = l + r >>> 1;
            if (check(mid, a, s)) r = mid;
            else l = mid + 1;
        }
        System.out.println(r);
    }

    private static boolean check(long t, int[] a, int[] s) {
    
    
        List<Pair<Long, Long>> v = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
    
    
            if (t >= s[i]) {
    
    
                v.add(new Pair<>(a[i] - (t - s[i]), a[i] + (t - s[i])));
            }
        }
        v.sort(Comparator.comparingLong(Pair::getKey));
        if (v.size() == 0 || v.get(0).getKey() > 1) return false;
        long r = v.get(0).getValue();
        for (int i = 1; i < v.size(); ++i) {
    
    
            if (v.get(i).getKey() <= r + 1) r = Math.max(r, v.get(i).getValue());
            else break;
        }
        return r >= m;
    }

    static class Pair<K, V> {
    
    
        private final K key;
        private final V value;

        public Pair(K key, V value) {
    
    
            this.key = key;
            this.value = value;
        }

        public K getKey() {
    
    
            return key;
        }

        public V getValue() {
    
    
            return value;
        }
    }
}
  • Python
n, m = map(int, input().split())
a = []
s = []
for i in range(n):
    a_i, s_i = map(int, input().split())
    a.append(a_i)
    s.append(s_i)

def check(t):
    v = []
    for i in range(n):
        if t >= s[i]:
            v.append((a[i] - (t - s[i]), a[i] + (t - s[i])))
    v.sort()
    if len(v) == 0 or v[0][0] > 1:
        return False
    r = v[0][1]
    for i in range(1, len(v)):
        if v[i][0] <= r + 1:
            r = max(r, v[i][1])
        else:
            break
    return r >= m

l = 1
r = 2_000_000_000
while l < r:
    mid = (l + r) // 2
    if check(mid):
        r = mid
    else:
        l = mid + 1

print(r)

Guess you like

Origin blog.csdn.net/m0_57487901/article/details/132741203