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;
                }
            }
        }
    }
    
  • 相关阅读:
    [状压dp][spfa] Jzoj P3737 挖宝藏
    [计算几何] Jzoj P3736 数学题
    [排序][vector] Jzoj P6288 旋转子段
    [区间dp] Jzoj P6287 扭动的树
    [bfs][spfa] Jzoj P6286 走格子
    [点分治] Luogu P2664 树上游戏
    [树链剖分][树状数组] Luogu P3676 小清新数据结构题
    [计算几何][dp] Luogu P1995 智能车比赛
    [后缀数组][并查集] Luogu P2178 品酒大会
    [莫比乌斯反演][整除分块] Bzoj P2301 Problem b
  • 原文地址:https://www.cnblogs.com/mollnn/p/14102401.html
Copyright © 2011-2022 走看看