• 【CodeForces】CF1700D River Locks


    题目地址:

    https://www.luogu.com.cn/problem/CF1700D

    题面翻译:
    n n n个容器,第 i i i个容器容量为 v i v_i vi升,可以容纳 [ 0 , v i ] [0,v_i] [0,vi]升的水。

    满出去的水会将从容器 i i i转移到容器 i + 1 i+1 i+1,如果 i + 1 i+1 i+1也满了会转移得更远。满出最后一个容器的水会倒到河中。

    现在要将所有容器填满。你可以选择一些容器注水,让这些容器每秒进入一升水。 q q q次询问,问最初所有容器都是空的,最少选择多少个容器注水使得 t i t_i ti秒内能填满所有容器。

    1 ≤ n , q ≤ 2 × 1 0 5 1\leq n,q\leq 2\times 10^5 1n,q2×105 1 ≤ v i , t i ≤ 1 0 9 1\leq v_i,t_i\leq 10^9 1vi,ti109

    题目描述:
    Recently in Divanovo, a huge river locks system was built. There are now n n n locks, the i i i -th of them has the volume of v i v_i vi liters, so that it can contain any amount of water between 0 0 0 and v i v_i vi liters. Each lock has a pipe attached to it. When the pipe is open, 1 1 1 liter of water enters the lock every second.

    The locks system is built in a way to immediately transfer all water exceeding the volume of the lock i i i to the lock i + 1 i + 1 i+1 . If the lock i + 1 i + 1 i+1 is also full, water will be transferred further. Water exceeding the volume of the last lock pours out to the river.
    The picture illustrates 5 5 5 locks with two open pipes at locks 1 1 1 and 3 3 3 . Because locks 1 1 1 , 3 3 3 , and 4 4 4 are already filled, effectively the water goes to locks 2 2 2 and 5 5 5 .To make all locks work, you need to completely fill each one of them. The mayor of Divanovo is interested in q q q independent queries. For each query, suppose that initially all locks are empty and all pipes are closed. Then, some pipes are opened simultaneously. For the j j j -th query the mayor asks you to calculate the minimum number of pipes to open so that all locks are filled no later than after t j t_j tj seconds.

    Please help the mayor to solve this tricky problem and answer his queries.

    输入格式:
    The first lines contains one integer n n n ( 1 ≤ n ≤ 200   000 1 \le n \le 200\,000 1n200000 ) — the number of locks.

    The second lines contains n n n integers v 1 , v 2 , … , v n v_1, v_2, \dots, v_n v1,v2,,vn ( 1 ≤ v i ≤ 1 0 9 1 \le v_i \le 10^9 1vi109 )) — volumes of the locks.

    The third line contains one integer q q q ( 1 ≤ q ≤ 200   000 1 \le q \le 200\,000 1q200000 ) — the number of queries.

    Each of the next q q q lines contains one integer t j t_j tj ( 1 ≤ t j ≤ 1 0 9 1 \le t_j \le 10^9 1tj109 ) — the number of seconds you have to fill all the locks in the query j j j .

    输出格式:
    Print q q q integers. The j j j -th of them should be equal to the minimum number of pipes to turn on so that after t j t_j tj seconds all of the locks are filled. If it is impossible to fill all of the locks in given time, print − 1 -1 1 .

    注意题目中说,每个水槽满了之后水都会漫到其右边那个水槽里,所以如果能装满的话,优先开最左边的若干个水龙头,这样使得水漫出右边界的情况尽可能少的发生。如果只考虑第 1 1 1个水槽,则至少需要 v 1 v_1 v1单位时间才能装满;如果只考虑前 2 2 2个水槽,那么如果两个水龙头一起开,如果不溢出的话,花的时间最少是 ⌈ v 1 + v 2 2 ⌉ \lceil \frac{v_1+v_2}{2} \rceil 2v1+v2,但是如果有溢出,意味着第 1 1 1个水槽还没装满,但是第 2 2 2个水槽已经漏水了,这个时候花的时间是 v 1 v_1 v1,所以综合两种情况,时间最少是 max ⁡ { v 1 , ⌈ v 1 + v 2 2 ⌉ } \max\{v_1,\lceil \frac{v_1+v_2}{2} \rceil\} max{v1,2v1+v2},以此类推,要装满所有水槽,时间最少是 t 0 = max ⁡ k ∑ i = 1 k v i k t_0=\max_k \frac{\sum_{i=1}^k v_i}{k} t0=maxkki=1kvi,先求出这个 t 0 t_0 t0,如果给出的询问 t < t 0 t<t_0 t<t0直接输出 − 1 -1 1

    如果 t ≥ t 0 t\ge t_0 tt0,那么至少是有解的,设解为 k k k,则 k ≥ ⌈ ∑ i = 1 n v i t ⌉ = k 0 k\ge \lceil \frac{\sum_{i=1}^n v_i}{t} \rceil=k_0 kti=1nvi=k0,但是 k 0 k_0 k0个水龙头事实上已经足够了,因为水只会向右边漫,只要开前 k 0 k_0 k0个水龙头,过了 t t t时间后,显然前 k 0 k_0 k0个水槽是满的,溢出前 k 0 k_0 k0个水槽的水刚好保证后面的水槽装满(可能有溢出,因为是上取整)。代码如下:

    #include <iostream>
    using namespace std;
    using LL = long long;
     
    const int N = 2e5 + 10;
    int n, q;
    LL a[N], low;
     
    int main() {
      scanf("%d", &n);
      for (int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
        a[i] += a[i - 1];
      }
     
      for (int i = 1; i <= n; i++) low = max(low, (a[i] + i - 1) / i);
     
      scanf("%d", &q);
      while (q--) {
        long t;
        scanf("%lld", &t);
        if (t < low) puts("-1");
        else printf("%lld\n", (a[n] + t - 1) / t);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    预处理时间复杂度 O ( n ) O(n) O(n),每次询问 O ( 1 ) O(1) O(1),空间 O ( 1 ) O(1) O(1)

  • 相关阅读:
    10 函数的连续性
    JUC并发编程——线程池学习:基础概念及三大方法、七大参数、四大拒绝策略(基于狂神说的学习笔记)
    Jenkins离线插件配置(二)
    什么是数字孪生?
    GESP 四级急救包(1):指针与地址
    javaScript能做什么
    游戏开发需不需要考研?
    Pikachu漏洞练习平台之XXE(XML外部实体注入)
    (38)Verilog实现序列10111【状态机一段式】
    HCIA4.26-5.10
  • 原文地址:https://blog.csdn.net/qq_46105170/article/details/125443610