• [CF52C] Circular RMQ


    Description

    给定一个环状序列,每次操作选择一个区间,整体加上一个数,或者询问最小值。

    Solution

    对于一个区间,如果 (l le r) 则映射到 ([l+1,r+1]);否则,映射到两个区间 ([l+1,n],[1,r+1]).

    线段树维护即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int n, m, src[N], a[N], tag[N];
    
    void put(int p, int v)
    {
        a[p] += v;
        tag[p] += v;
    }
    
    void pushup(int p)
    {
        a[p] = min(a[p * 2], a[p * 2 + 1]);
    }
    
    void pushdown(int p, int l, int r)
    {
        if (tag[p])
        {
            put(p * 2, tag[p]);
            put(p * 2 + 1, tag[p]);
            tag[p] = 0;
        }
    }
    
    void build(int p, int l, int r)
    {
        if (l == r)
        {
            a[p] = src[l];
        }
        else
        {
            build(p * 2, l, (l + r) / 2);
            build(p * 2 + 1, (l + r) / 2 + 1, r);
            pushup(p);
        }
    }
    
    void modify(int p, int l, int r, int ql, int qr, int v)
    {
        if (l > qr || r < ql)
            return;
        if (l >= ql && r <= qr)
        {
            put(p, v);
        }
        else
        {
            pushdown(p, l, r);
            modify(p * 2, l, (l + r) / 2, ql, qr, v);
            modify(p * 2 + 1, (l + r) / 2 + 1, r, ql, qr, v);
            pushup(p);
        }
    }
    
    int query(int p, int l, int r, int ql, int qr)
    {
        if (l > qr || r < ql)
            return 1e18;
        if (l >= ql && r <= qr)
        {
            return a[p];
        }
        else
        {
            pushdown(p, l, r);
            return min(query(p * 2, l, (l + r) / 2, ql, qr), query(p * 2 + 1, (l + r) / 2 + 1, r, ql, qr));
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> src[i];
    
        build(1, 1, n);
    
        cin >> m;
        string str;
        getline(cin, str);
        for (int i = 1; i <= m; i++)
        {
            string str;
            getline(cin, str);
            stringstream ss;
            ss << str;
            int t1, t2, t3;
            ss >> t1 >> t2;
            if (ss >> t3)
            {
                if (t1 <= t2)
                {
                    modify(1, 1, n, t1 + 1, t2 + 1, t3);
                }
                else
                {
                    modify(1, 1, n, t1 + 1, n, t3);
                    modify(1, 1, n, 1, t2 + 1, t3);
                }
            }
            else
            {
                if (t1 <= t2)
                {
                    cout << query(1, 1, n, t1 + 1, t2 + 1) << endl;
                }
                else
                {
                    cout << min(query(1, 1, n, t1 + 1, n), query(1, 1, n, 1, t2 + 1)) << endl;
                }
            }
        }
    }
    
  • 相关阅读:
    关于Java中String类的hashCode方法
    重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源
    vue+eslint+prettier+vetur 使用vscode 前端工程化
    vue webpack 打包优化
    移动端兼容
    vue 跨域使用
    vue2.0性能优化
    前端 mock的使用
    vue 使用Lodash 的throttle(节流)与debounce(防抖
    webpack4 安装及使用
  • 原文地址:https://www.cnblogs.com/mollnn/p/14102401.html
Copyright © 2020-2023  润新知