@yuyuesheng
2019-02-17T20:51:22.000000Z
字数 1228
阅读 778
题意:
有两种操作,一种是环上的区间加,一种是环上的区间最值
题解:
线段树区间更新模板
#include<iostream>
#include <cstring>
#include<string>
#include <algorithm>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using 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;
else
cout << min(Query(1, r, 1, n, 1), Query(l, n, 1, n, 1)) << endl;
}
}
}