zoukankan      html  css  js  c++  java
  • 「CF52C」Circular RMQ

    更好的阅读体验

    Portal

    Portal1: Codeforces

    Portal2: Luogu

    Description

    You are given circular array (a_0, a_1, cdots, a_{n - 1}). There are two types of operations with it:

    • ( extrm{inc}(lf, rg, v)) — this operation increases each element on the segment ([lf, rg]) (inclusively) by (v);

    • ( extrm{rmq}(lf, rg)) — this operation returns minimal value on the segment ([lf, rg]) (inclusively).

    Assume segments to be circular, so if (n = 5) and (lf = 3, rg = 1), it means the index sequence: (3, 4, 0, 1).

    Write program to process given sequence of operations.

    Input

    The first line contains integer (n (1 le n le 200000)). The next line contains initial state of the array: (a_0, a_1, cdots, a_{n - 1} ( -10^6 le ai le 10^6)), (a_i) are integer. The third line contains integer (m (0 le m le 200000)), (m) — the number of operartons. Next (m) lines contain one operation each. If line contains two integer (lf, rg (0 le lf, rg le n - 1)) it means rmq operation, it contains three integers (lf, rg, v (0 le lf, rg le n - 1; -10^6 le v le 10^6)) — inc operation.

    Output

    For each rmq operation write result for it. Please, do not use %lld specificator to read or write (64)-bit integers in C++. It is preffered to use cout (also you may use %I64d).

    Sample Input

    4
    1 2 3 4
    4
    3 0
    3 0 -1
    0 1
    2 1
    

    Sample Output

    1
    0
    0
    

    Solution

    我们可以用线段树来解决区间RMQ问题,我们在线段树上维护一个最小值与懒标记,这样问题就解决了。

    读入的时候我们可以判断后面一个字符是不是空格,可以直接在快速读入里判断,这样就可以判断出一行有三个数还是两个数。

    Code

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    
    using namespace std;
    
    const int MAXN = 200005;
    int n, m, l, r, val, a[MAXN];
    bool opt;
    namespace Segtree {
        #define ls rt << 1
        #define rs rt << 1 | 1
        typedef long long LL;
        const LL Seg_INF = 1e18;
        const int Seg_MAXN = 1000005;
        struct SMT {
            LL Min, tag;
        } tree[Seg_MAXN];
        inline void build(int rt, int l, int r) {//建立线段树
            if (l == r) {
                tree[rt].Min = a[l];
                return ;
            }
            int mid = l + r >> 1;
            build(ls, l, mid);
            build(rs, mid + 1, r);
            tree[rt].Min = min(tree[ls].Min, tree[rs].Min);
        }
        inline void update(int rt, int l, int r, int ansl, int ansr, int val) {//线段树修改
            if (ansl <= l && r <= ansr) {
                tree[rt].tag += val;
                return ;
            }
            int mid = l + r >> 1;
            if (ansl <= mid) update(ls, l, mid, ansl, ansr, val);
            if (mid < ansr) update(rs, mid + 1, r, ansl, ansr, val);
            tree[rt].Min = min(tree[ls].Min + tree[ls].tag, tree[rs].Min + tree[rs].tag);
        }
        inline LL query(int rt, int l, int r, int ansl, int ansr) {//线段树查询
            if (ansl <= l && r <= ansr) return tree[rt].Min + tree[rt].tag;
            int mid = l + r >> 1;
            LL ret = Seg_INF;
            if (ansl <= mid) ret = min(ret, query(ls, l, mid, ansl, ansr));
            if (mid < ansr) ret = min(ret, query(rs, mid + 1, r, ansl, ansr));
            return ret + tree[rt].tag;
        }
    }
    
    using namespace Segtree;
    
    inline int read() {
        opt = 0;
        char ch = getchar();
        int x = 0, f = 1;
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while ('0' <= ch && ch <= '9') {
            x = (x << 1) + (x << 3) + ch - '0';
            ch = getchar();
        }
        if (ch == ' ') opt = 1;//判断空格
        return x * f;
    }
    int main() {
        n = read();
        for (int i = 1; i <= n; i++)
            a[i] = read();
        build(1, 1, n);
        m = read();
        for (int i = 1; i <= m; i++) {
            l = read(); r = read(); l++; r++;
            if (!opt) {
                if (l <= r) printf("%lld
    ", query(1, 1, n, l, r)); else printf("%lld
    ", min(query(1, 1, n, l, n), query(1, 1, n, 1, r)));
            } else {
                val = read();
                if (l <= r) update(1, 1, n, l, r, val); else {
                    update(1, 1, n, l, n, val);
                    update(1, 1, n, 1, r, val);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    让你的 Python 代码优雅又地道
    Python3简单爬虫抓取网页图片
    Python 全集变量
    python-ConfigParser模块【读写配置文件】
    Python 第三方插件库
    Python 安装 lxml 插件
    Python cmd中输入'pip' 不是内部或外部命令,也不是可运行的程序或批处理文件。
    SQLServer代理新建或者编辑作业报错
    Python pycharm 常用快捷键
    python 安装插件 requests、BeautifulSoup
  • 原文地址:https://www.cnblogs.com/shenxiaohuang/p/11623029.html
Copyright © 2011-2022 走看看