HDU 1166 敌兵布阵 线段树
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1166
题目大意: 有一串儿数, 可以对某一个数加减或者对某一区间进行加和。
解题思路: 最基础的单点更新和区间加和的线段树
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <string> #include <vector> #include <map> #include <cstring> #include <iterator> #include <cmath> #include <algorithm> #include <stack> #include <deque> #include <map> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 const int maxn = 50000+7; using namespace std; int sum[4*maxn]; int arr[maxn]; char op[10]; void pushPlus( int rt ) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void build( int l, int r, int rt ) { if( l == r ) { sum[rt] = arr[l]; return; } int m = (l + r) >> 1; build(lson); build(rson); pushPlus(rt); } void Update( int p, int add, int l, int r, int rt ) { if( l == r ) { sum[rt] += add; return; } int m = (l + r) >> 1; if( p <= m ) { Update( p, add, lson ); } else Update( p, add, rson ); pushPlus(rt); } int Query( int L, int R, int l, int r, int rt ) { if( L <= l && r <= R ) { return sum[rt]; } int m = (l + r) >> 1; int ans = 0; if( L <= m ) ans += Query(L, R, lson); if( R > m ) ans += Query(L, R, rson); return ans; } int main() { int t; scanf( "%d", &t ); for( int cases = 1; cases <= t; cases++ ) { printf( "Case %d:\n", cases ); int n; scanf( "%d", &n ); for( int i = 1; i <= n; i++ ) { scanf( "%d", &arr[i] ); } build(1, n, 1); while( scanf( "%s", op ) && op[0] != 'E' ) { int a, b; scanf( "%d%d", &a, &b ); if( op[0] == 'Q' ) { printf( "%d\n", Query(a, b, 1, n, 1) ); } else if( op[0] == 'A' ) { Update( a, b, 1, n, 1 ); } else { Update( a, -b, 1, n, 1 ); } } } return 0; }
思考: 看了昨天多校的题, 发现没几道题能做, 所以现在开始学习线段树, 自己写代码的时候还是会有好多bug,主要是自己的思路没理清, 对树的理解不够深
posted on 2017-08-04 15:11 FriskyPuppy 阅读(100) 评论(0) 编辑 收藏 举报