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;
    }
    
  • 相关阅读:
    MOSS中的User的Title, LoginName, DisplayName, SID之间的关系
    如何在Network Monitor中高亮间隔时间过长的帧?
    SharePoint服务器如果需要安装杀毒软件, 需要注意什么?
    如何查看SQL Profiler? 如何查看SQL死锁?
    什么是Telnet
    The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
    Windows SharePoint Service 3.0的某个Web Application无搜索结果
    网络连接不上, 有TCP错误, 如果操作系统是Windows Server 2003, 请尝试一下这里
    在WinDBG中查看内存的命令
    The virtual machine could not be started because the hypervisor is not running
  • 原文地址:https://www.cnblogs.com/shenxiaohuang/p/11623029.html
Copyright © 2011-2022 走看看