zoukankan      html  css  js  c++  java
  • CodeForces 1109C. Sasha and a Patient Friend

    题目简述:维护以下三种操作

    1. "1 t s":在时刻$t$插入命令$s$。保证任意操作后,任意时刻至多只有一个命令。

    2. "2 t":删除时刻$t$的命令。

    3. "3 l r v":求最小的$t in [l, r]$,使得$f(t)=0$,其中

    $$ f(t) = v+int_l^t g(x) mathrm{d} x, $$

    其中设在$[l, r]$时间内的命令依次为$(t_1, s_1), dots, (t_m, s_m)$,则

    $$ g(t) = egin{cases}
    0 & l leq t < t_1 \
    s_1 & t_1 leq t < t_2 \
    dots \
    s_k & t_k leq t < t_{k+1} \
    dots \
    s_m & t geq t_m
    end{cases}. $$

    若不存在,则返回$-1$。

    解:code

    相关题目:[NOI2005]维护数列

    我们将3种操作翻译为以下三种操作:

    1. "1 t s":设时刻$t$之后的下一个命令的时刻是$t' > t$。则将$[t, t')$整个区间赋值为$s$。

    2. "2 t":设时刻$t$的相邻命令的时刻是$t_1$和$t_2$,满足$t_1 < t < t_2$,并且$t_1$时刻的命令是$s_1$。则将$[t, t_2)$整个区间赋值为$s_1$。

    3. "3 l r v":设时刻$l$之后最近的命令在时刻$t_0 geq l$,令$mathit{lsum}$表示$[t_0, r)$区间上最小的前缀和,若$v+mathit{lsum} leq 0$,则存在时刻$t in [t_0, r]$,使得$f(t) = 0$。而找到具体的$t$,则可用二分法。

    以上三个操作均可用线段树来维护,令

    struct node
    {
        node *Lc, *Rc; //线段树左右儿子
        int flag, set; //是否区间赋值,具体赋值
        ll lsum, sum;  //lsum如上定义,sum为区间求和
    };
    

      

    则可以通过以下方式维护信息

    void update(node *p)
    {
        p->sum = p->Lc->sum+p->Rc->sum;
        p->lsum = min(p->Lc->lsum, p->Lc->sum+p->Rc->lsum);
    }
    

      

    从而时间复杂度为$O(q log V)$,其中$q$为操作个数,$V$为时刻的取值范围。

    注:可预先离散化,或用平衡树来维护,将时间复杂度降至$O(q log q)$。

  • 相关阅读:
    Linux systemtap定位系统IO资源使用情况(ok)
    DISK 100% BUSY,谁造成的?(ok)
    容易被误读的IOSTAT
    利用BLKTRACE分析IO性能
    iowait 过高问题的查找及解决linux
    top后台执行显示:top: failed tty get 错误
    Nginx解读内置非默认模块 ngx_http_stub_status_module
    Nginx健康检查模块
    平滑升级你的Nginx
    Practice telephone techniques
  • 原文地址:https://www.cnblogs.com/TinyWong/p/10400682.html
Copyright © 2011-2022 走看看