线段树入门(个人习惯模板)--士兵杀敌

来源:互联网 发布:dw制作淘宝首页教程 编辑:程序博客网 时间:2024/05/21 07:58

首先这题先确定个人做线段树的规范, 采用结构体存储,好处之一就是可以放很多东西,类型也可以不一样,随时增减属性

当然,开多个数组存也是可以的,但个人不习惯这样用;


接下来这题用来线段树入门

单点更新:最最基础的线段树,只更新叶子节点,然后把信息用PushUP(int r)这个函数更新上来

  • hdu1166 敌兵布阵
    题意:O(-1)
    思路:O(-1)
    线段树功能:update:单点增减 query:区间求和

代码如下:

#include <cstdio> #define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 55555;struct Tree{int value;}tree[maxn<<2];void PushUP(int rt) {tree[rt].value = tree[rt<<1].value + tree[rt<<1|1].value;}void build(int l,int r,int rt) {if (l == r) {scanf("%d",&tree[rt].value);return ;}int m = (l + r) >> 1;build(lson);build(rson);PushUP(rt);}void update(int p,int add,int l,int r,int rt) {//p表示要进行操作的人是第几个if (l == r) { tree[rt].value += add;return ;}int m = (l + r) >> 1;if (p <= m) update(p , add , lson);else update(p , add , rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt) {if (L <= l && r <= R) {return tree[rt].value;}int m = (l + r) >> 1;int ret = 0;if (L <= m) ret += query(L , R , lson);if (R > m) ret += query(L , R , rson);return ret;}int main() {int T , n;scanf("%d",&T);for (int cas = 1 ; cas <= T ; cas ++) {printf("Case %d:\n",cas);scanf("%d",&n);build(1 , n , 1);char op[10];while (scanf("%s",op)) {if (op[0] == 'E') break;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] == 'S') update(a , -b , 1 , n , 1);else update(a , b , 1 , n , 1);}}return 0;}


0 0