原题链接:http://ac.jobdu.com/problem.php?pid=1407
线段树,区间更新,查询区间最小值。
注意区间更新,查询的时候,区间$\begin{align*}[L,R] \end{align*}$$\begin{align*}L \end{align*}$都可能大于$\begin{align*}R\end{align*}$。。
有个地方写sb了害的我wa了好几次%>_<%。
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #define lc root<<1 7 #define rc root<<1|1 8 #define mid ((l+r)>>1) 9 using std::min; 10 const int Max_N = 100010; 11 const int INF = ~0u >> 1; 12 struct Node { 13 int val, add; 14 }; 15 struct SegTree { 16 Node seg[Max_N << 2]; 17 inline void push_up(int root) { 18 seg[root].val = min(seg[lc].val, seg[rc].val); 19 } 20 inline void built(int root, int l, int r) { 21 seg[root].add = 0; 22 if (l == r) { 23 scanf("%d", &seg[root].val); 24 return; 25 } 26 built(lc, l, mid); 27 built(rc, mid + 1, r); 28 push_up(root); 29 } 30 inline void push_down(int root) { 31 if (seg[root].add != 0) { 32 int &_add = seg[root].add; 33 seg[lc].add += _add; 34 seg[lc].val += _add; 35 seg[rc].add += _add; 36 seg[rc].val += _add; 37 _add = 0; 38 } 39 } 40 inline void update(int root, int l, int r, int x, int y, int v) { 41 if (x > r || y < l) return; 42 if (x <= l && y >= r) { 43 seg[root].add += v; 44 seg[root].val += v; 45 return; 46 } 47 push_down(root); 48 update(lc, l, mid, x, y, v); 49 update(rc, mid + 1, r, x, y, v); 50 push_up(root); 51 } 52 inline int query(int root, int l, int r, int x, int y) { 53 if (x > r || y < l) return INF; 54 if (x <= l && y >= r) return seg[root].val; 55 push_down(root); 56 int v1 = query(lc, l, mid, x, y); 57 int v2 = query(rc, mid + 1, r, x, y); 58 return min(v1, v2); 59 } 60 }seg; 61 int main() { 62 #ifdef LOCAL 63 freopen("in.txt", "r", stdin); 64 freopen("out.txt", "w+", stdout); 65 #endif 66 char buf[100]; 67 int n, m, a, b, c; 68 while (~scanf("%d", &n)) { 69 seg.built(1, 1, n); 70 scanf("%d\n", &m); 71 while (m--) { 72 gets(buf); 73 char *p = strchr(buf, ' '); 74 if (strchr(++p, ' ')) { 75 sscanf(buf, "%d %d %d", &a, &b, &c); 76 if (a <= b) { 77 seg.update(1, 1, n, ++a, ++b, c); 78 } else { 79 seg.update(1, 1, n, ++a, n, c); 80 seg.update(1, 1, n, 1, ++b, c); 81 } 82 } else { 83 sscanf(buf, "%d %d", &a, &b); 84 if (a <= b) { 85 printf("%d\n", seg.query(1, 1, n, ++a, ++b)); 86 } else { 87 int v1 = seg.query(1, 1, n, ++a, n); 88 int v2 = seg.query(1, 1, n, 1, ++b); 89 printf("%d\n", min(v1, v2)); 90 } 91 } 92 } 93 } 94 return 0; 95 }