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;
    }
    
  • 相关阅读:
    JavaEE——SpringMVC(11)--拦截器
    JavaEE——SpringMVC(10)--文件上传 CommonsMultipartResovler
    codeforces 460A Vasya and Socks 解题报告
    hdu 1541 Stars 解题报告
    hdu 1166 敌兵布阵 解题报告
    poj 2771 Guardian of Decency 解题报告
    hdu 1514 Free Candies 解题报告
    poj 3020 Antenna Placement 解题报告
    BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告
    poj 1325 Machine Schedule 解题报告
  • 原文地址:https://www.cnblogs.com/shenxiaohuang/p/11623029.html
Copyright © 2011-2022 走看看