[Usaco2015 DEC] Counting Haybales
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=4392
[算法]
线段树
时间复杂度 : O(MlogN)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 200010 typedef long long LL; int n , m; LL a[MAXN]; struct SegmentTree { struct Node { int l , r; LL sum , val; LL tag; } Tree[MAXN << 2]; inline void build(int index , int l , int r) { Tree[index].l = l; Tree[index].r = r; Tree[index].tag = 0; if (l == r) { Tree[index].sum = Tree[index].val = a[l]; return; } int mid = (l + r) >> 1; build(index << 1 , l , mid); build(index << 1 | 1 , mid + 1 , r); update(index); } inline void update(int index) { Tree[index].sum = Tree[index << 1].sum + Tree[index << 1 | 1].sum; Tree[index].val = min(Tree[index << 1].val , Tree[index << 1 | 1].val); } inline void pushdown(int index) { int l = Tree[index].l , r = Tree[index].r; int mid = (l + r) >> 1; Tree[index << 1].sum += Tree[index].tag * (mid - l + 1); Tree[index << 1 | 1].sum += Tree[index].tag * (r - mid); Tree[index << 1].val += Tree[index].tag; Tree[index << 1 | 1].val += Tree[index].tag; Tree[index << 1].tag += Tree[index].tag; Tree[index << 1 | 1].tag += Tree[index].tag; Tree[index].tag = 0; } inline void modify(int index , int l , int r , LL value) { if (Tree[index].l == l && Tree[index].r == r) { Tree[index].sum += (r - l + 1) * value; Tree[index].val += value; Tree[index].tag += value; return; } pushdown(index); int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) modify(index << 1 , l , r , value); else if (mid + 1 <= l) modify(index << 1 | 1 , l , r , value); else { modify(index << 1 , l , mid , value); modify(index << 1 | 1 , mid + 1 , r , value); } update(index); } inline LL query_sum(int index , int l , int r) { if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum; pushdown(index); int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) return query_sum(index << 1 , l , r); else if (mid + 1 <= l) return query_sum(index << 1 | 1 , l , r); else return query_sum(index << 1 , l , mid) + query_sum(index << 1 | 1 , mid + 1 , r); } inline LL query_min(int index , int l , int r) { if (Tree[index].l == l && Tree[index].r == r) return Tree[index].val; pushdown(index); int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) return query_min(index << 1 , l , r); else if (mid + 1 <= l) return query_min(index << 1 | 1 , l , r); else return min(query_min(index << 1 , l , mid) , query_min(index << 1 | 1 , mid + 1 , r)); } } T; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } int main() { read(n); read(m); for (int i = 1; i <= n; i++) read(a[i]); T.build(1 , 1 , n); while (m--) { char op[5]; scanf("%s",op); if (op[0] == 'P') { int l , r; LL x; read(l); read(r); read(x); T.modify(1 , l , r , x); } if (op[0] == 'S') { int l , r; read(l); read(r); printf("%lld\n" , T.query_sum(1 , l ,r)); } if (op[0] == 'M') { int l , r; read(l); read(r); printf("%lld\n", T.query_min(1 , l , r)); } } return 0; }