@yuyuesheng
2019-02-17T12:51:22.000000Z
字数 1228
阅读 906
题意:
有两种操作,一种是环上的区间加,一种是环上的区间最值
题解:
线段树区间更新模板
#include<iostream>#include <cstring>#include<string>#include <algorithm>#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1using namespace std;typedef long long ll;const int maxn = 2e5 + 5000;const ll inf = 1e18;ll mi[maxn << 2], add[maxn << 2];int n, q;void PushUp(int rt){mi[rt] = min(mi[rt << 1], mi[rt << 1 | 1]);}void PushDown(int rt){if (add[rt]){mi[rt << 1] += add[rt];mi[rt << 1 | 1] += add[rt];add[rt << 1] += add[rt];add[rt << 1 | 1] += add[rt];add[rt] = 0;}}void Build(int l, int r, int rt = 1){add[rt] = 0;if (l == r){cin >> mi[rt];return;}int mid = (l + r) >> 1;Build(lson);Build(rson);PushUp(rt);}void Update(int L, int R, int c, int l, int r, int rt){if (L <= l && r <= R){mi[rt] += c;add[rt] += c;return;}int mid = (l + r) >> 1;PushDown(rt);if (L <= mid)Update(L, R, c, lson);if (mid < R)Update(L, R, c, rson);PushUp(rt);}ll Query(int L, int R, int l, int r, int rt){if (L <= l && r <= R)return mi[rt];int mid = (l + r) >> 1;ll ans = inf;PushDown(rt);if (L <= mid)ans = min(ans, Query(L, R, lson));if (mid < R)ans = min(ans, Query(L, R, rson));return ans;}int main(){cin >> n;Build(1, n, 1);cin >> q;while (q--){int l, r, c;cin >> l >> r;l++;r++;if (getchar() == ' '){cin >> c;if (l <= r)Update(l, r, c, 1, n, 1);else{Update(1, r, c, 1, n, 1);Update(l, n, c, 1, n, 1);}}else{if (l <= r)cout << Query(l, r, 1, n, 1) << endl;elsecout << min(Query(1, r, 1, n, 1), Query(l, n, 1, n, 1)) << endl;}}}