zoukankan      html  css  js  c++  java
  • [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;
                }
            }
        }
    }
    
  • 相关阅读:
    BZOJ1001 BJOI2006狼抓兔子(最小割+最短路)
    BZOJ4569 SCOI2016萌萌哒(倍增+并查集)
    Luogu4782 【模板】2-SAT 问题(2-SAT)
    BZOJ3626 LNOI2014LCA(树链剖分+主席树)
    BZOJ4012 HNOI2015开店(树链剖分+主席树)
    Luogu2264 树上游戏(点分治)
    BZOJ3998 TJOI2015弦论(后缀数组+二分答案)
    BZOJ1045 HAOI2008糖果传递(贪心)
    BZOJ1124 POI2008枪战Maf(环套树+贪心)
    洛谷 P4568 [JLOI2011]飞行路线 解题报告
  • 原文地址:https://www.cnblogs.com/mollnn/p/14102401.html
Copyright © 2011-2022 走看看