C. Circular RMQ
题目大意:
好激动,带懒标记的上百行的线段树带A掉这道题,线段树真好玩,可以看出来是裸的带懒标记的线段树
难点1:读入的时候怎么判断是3个数还是2个数,看快读最后有无读入空格,如果读入了space就等于1
难点2:线段是环形的l <= r正常区间,l > r 就讲区间分成 1 ~ r, l ~ n, 读入的是0~n-1我们处理成1 ~ n
难点3:线段树和懒标记,我也是初学者不会讲,找大佬学呗
Ac code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll w[N];
struct Node{
ll l, r, minv, lazy;
}tr[N << 2];
int space;
inline ll read()
{
space = 0;
ll x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
space = c == ' ';
return x * f;
}
inline void print(ll x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
}
inline ll ls(ll u) {return u << 1; }
inline ll rs(ll u) {return u << 1 | 1; }
inline void pushup(ll u, ll l, ll r){
tr[u] = {l, r, min(tr[ls(u)].minv, tr[rs(u)].minv), 0};
}
inline void pushdown(ll u){
if(tr[u].lazy){ //懒标记
tr[ls(u)].minv += tr[u].lazy;
tr[rs(u)].minv += tr[u].lazy;
tr[ls(u)].lazy += tr[u].lazy;
tr[rs(u)].lazy += tr[u].lazy;
tr[u].lazy = 0;
}
}
void build(ll u, ll l, ll r)
{
if(l == r){
tr[u] = {l, r, w[l], 0};
return;
}
ll mid = l + r >> 1;
build(ls(u), l, mid);
build(rs(u), mid + 1, r);
pushup(u, l, r);
}
void modify(ll u, ll l, ll r, ll x)
{
if(l <= tr[u].l && tr[u].r <= r)
{
tr[u].minv += x;
tr[u].lazy += x;
return;
}
pushdown(u);
ll mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(ls(u), l, r, x);
if(mid < r) modify(rs(u), l, r, x);
pushup(u, tr[u].l, tr[u].r);
}
ll query(ll u, ll l, ll r)
{
if(l <= tr[u].l && tr[u].r <= r)
return tr[u].minv;
pushdown(u);
ll mid = tr[u].l + tr[u].r >> 1, minv = __INT64_MAX__;
if(l <= mid) minv = min(minv, query(ls(u), l, r));
if(mid < r) minv = min(minv, query(rs(u), l, r));
return minv;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif
ll n = read();
for(int i = 1; i <= n; ++i) w[i] = read();
build(1, 1, n); //建树
ll m = read();
while(m--)
{
ll x = read(), y = read();
if(space) //inc
{
ll v = read();
++x, ++y;
if(x <= y)
modify(1, x, y, v);
else
modify(1, 1, y, v), modify(1, x, n, v);
}
else //rmq
{
++x, ++y;
if(x <= y)
{
print(query(1, x, y));
putchar('\n');
}
else
{
print(min(query(1, 1, y), query(1, x, n)));
putchar('\n');
}
}
}
return 0;
}
今天是被大运河虐惨的一天… ---------------------------------------------------------------------------------------------2021.12.18