一、题意

  给定一个元素个数为$N(1 \le N \le 10^5)$初始序列$a$和$b$,$a$序列的初始值全为$0$,$b$序列的初始值为$1$到$N$的一个排列。有$T(1 \le T \le 10^5)$次操作。操作有如下两种类型:

1、$add\ l\ r$:给序列$a$的区间$[l, r]$内所有元素加$1$;

2、$query\ l\ r$:查询$\sum\limits_{i=l}^{r}\lfloor{\frac{a_i}{b_i}}\rfloor$,并输出。

二、简要思路概括

  因为所有操作的总和$tot \le \sum\limits_{i=1}^{N}\frac{T}{i} = T * \sum\limits_{i=1}^{N}\frac{1}{i}$,而可证明调和级数$T * \sum\limits_{i=1}^{N}\frac{1}{i} \le TlogN$。

  所以,建立两棵线段树。一棵树$B$维护$b$序列的区间最小值,可支持区间修改。另一棵树$C$维护$\lfloor{\frac{a_i}{b_i}}\rfloor$的区间和。

  每次遇到$add$操作时,将$B$线段树的区间$[l, r]$减$1$,时间复杂度$O(logN)$。然后,再对线段树$B$做一遍dfs,如果有叶子节点的值为$0$,则把线段树$C$的对应位置加$1$,同时将该位置的值设置为初始的$b$值。时间复杂度$O(N)$。

  所以,单次$add$操作的时间复杂度是$O(N)$,总的时间复杂度是$O(N*T)$。但是,不要觉得会超时。实际的计算量并没有这么大。因为前面已证明,最多只会累加$T \times logN$次。所以,只要代码写得优雅,绝对不会超时。另外,还有一种写法,就是每次对线段树$B$做区间减$1$之后,循环查询$B$线段树的$[l, r]$区间内的最小值,如果最小值为$0$,则把线段树$C$的对应位置加$1$,同时修改该位置的值为初始的$b$值,直到该区间内的最小值不为$0$为止。这样,总的时间复杂度是$O(T*NlogN)$,也不会超时。

三、代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
typedef long long ll;
struct Node1 {
    int mv, lazy;
};
struct Node2 {
    int v, sum;
};
Node1 b[MAXN * ];
Node2 c[MAXN * ];
int b0[MAXN], N, Q;

void push_down(int rt) {
    if(b[rt].lazy) {
        , rch = rt <<  | ;
        b[lch].mv += b[rt].lazy, b[lch].lazy += b[rt].lazy;
        b[rch].mv += b[rt].lazy, b[rch].lazy += b[rt].lazy;
        b[rt].mv = min(b[rt << ].mv, b[rt <<  | ].mv);
        b[rt].lazy = ;
    }
}

, , int r = N) {
    if(l >= ul && r <= ur) {
        if(f)b[rt].mv = val;
        else b[rt].mv += val, b[rt].lazy += val;
        return;
    }
    push_down(rt);
    ;
    , l, mid);
     | , mid + , r);
    b[rt].mv = min(b[rt << ].mv, b[rt <<  | ].mv);
}

, , int r = N) {
    if(l == r && l == p) {
        c[rt].v++, c[rt].sum++;
        return;
    }
    ;
    , l, mid);
     | , mid + , r);
    c[rt].sum = c[rt << ].sum + c[rt <<  | ].sum;
}

, , int r = N) {
    if(ql <= l && qr >= r)return c[rt].sum;
    , res = ;
    , l, mid);
     | , mid + , r);
    return res;
}

, , int r = N) {
    if(l == r) {
        b[rt].mv = b0[l], update2(l);
        return;
    }
    push_down(rt);
    ;
    ].mv == )dfs(ul, ur, rt << , l, mid);
     | ].mv == )dfs(ul, ur, rt <<  | , mid + , r);
    b[rt].mv = min(b[rt << ].mv, b[rt <<  | ].mv);
}

int main() {
//    freopen("input.txt", "r", stdin);
    ];
    int l, r;
    while(~scanf("%d%d", &N, &Q)) {
        , tt = N << ; i < tt; ++i)b[i].mv = INT_MAX, b[i].lazy = ;
        memset(c, , sizeof(c));
        ; i <= N; ++i)scanf();
        while(Q--) {
            scanf("%s%d%d", cmd, &l, &r);
            ] == 'a') {
                update1(l, r, -, );
                dfs(l, r);
            }
            else cout << query2(l, r) << endl;
        }
    }
    ;
}

2018 Multi-University Training Contest 2-1007(hdu 6315)-题解的更多相关文章

  1. hdu 4941 2014 Multi-University Training Contest 7 1007

    Magical Forest Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  2. 2017 Multi-University Training Contest - Team 2 &&hdu 6050 Funny Function

    Funny Function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. 2017 Multi-University Training Contest - Team 2 &&hdu 6053 TrickGCD

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  4. 2017 Multi-University Training Contest - Team 2&&hdu 6047 Maximum Sequence

    Maximum Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. hdu 6315 Naive Operations (2018 Multi-University Training Contest 2 1007)

    Naive Operations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Other ...

  6. HDU 6356.Glad You Came-线段树(区间更新+剪枝) (2018 Multi-University Training Contest 5 1007)

    6356.Glad You Came 题意就是给你一个随机生成函数,然后从随机函数里确定查询的左右区间以及要更新的val值.然后最后求一下异或和就可以了. 线段树,区间最大值和最小值维护一下,因为数据 ...

  7. HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)

    6315.Naive Operations 题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置 ...

  8. 【2018 Multi-University Training Contest 2 1007】Naive Operations

    [链接] 我是链接,点我呀:) [题意] 给你两个数组a,b; b数组是1..n的一个排列. 现在给你两种操作: add l,r将a[l..r]都加上1 query l,r 询问$∑^r_l\frac ...

  9. 2018 Nowcoder Multi-University Training Contest 2

    目录 Contest Info Solutions A. run D. monrey G. transform H. travel I. car J. farm Contest Info Practi ...

随机推荐

  1. "CMAKE_CXX_COMPILER-NOTFOUND"

    CMake Error: your CXX compiler: "CMAKE_CXX_COMPILER-NOTFOUND" was not found. Please set CM ...

  2. vs_u8前缀

    1.ZC: 个人测试下来,VS2015开始 支持 u8前缀. 2.What's New for Visual C++ in Visual Studio 2015 https://msdn.micros ...

  3. InfiniBand 与Intel Omni-Path Architecture

    Intel Omni-Path Architecture (OPA) 是一种与InfiniBand相似的网络架构 可以用来避免以下PCI总线一些缺陷: 1.由于采用了基于总线的共享传输模式,在PCI总 ...

  4. 指定html转pdf文档

    1.资源 <script type="text/javascript" src="./js/canvg2.js"></script> & ...

  5. Page.TryUpdateModel 方法

    使用来自值提供程序的值更新指定的模型实例. 使用来自值提供程序的值更新指定的模型实例. 命名空间:   System.Web.UI程序集:  System.Web(System.Web.dll 中) ...

  6. 伸展树的基本操作——以【NOI2004】郁闷的出纳员为例

    前两天老师讲了伸展树……虽然一个月以前自己就一直在看平衡树这一部分的书籍,也仔细地研读过伸展树地操作代码,但是就是没写过程序……(大概也是在平衡树的复杂操作和长代码面前望而生畏了)但是今天借着老师布置 ...

  7. 从 TWAIN 设备中扫描图像

    转自(http://yonsm.net/scan-images-from-a-twain-device/) 一.简介 TWAIN 数据源管理程序 (DSM) 工业标准的软件库,用于从静态图像设备提取图 ...

  8. idea常用实用快捷键

    Ctrl+Alt+方向键(左键,右键),返回上次查看的位置.(这个快捷键和window本身快捷键冲突,需要关闭windows 对应快捷键功能,参考博客:https://blog.csdn.net/u0 ...

  9. 重构 demo篇

    本文背景为学习重构一书中的一些信息的记录. 该篇以一个影片租赁为背景.通过一层层的重构,最终实现相对来说比较完美的代码. 文中经典语句摘要: “如果它没有坏,就不要动它 .” 用来形容我们工作中一些比 ...

  10. 1月中旬值得一读的10本技术新书(机器学习、Java、大数据等)!

    1月中旬,阿里云云栖社区 联合 博文视点 为大家带来十本技术书籍(机器学习.Java.大数据等).以下为书籍详情,文末还有福利哦! 书籍名称:Oracle数据库问题解决方案和故障排除手册 内容简介 & ...