HDU 1166 敌兵布阵 (线段树 单点更新)

题目链接

线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯。。就从这个题开始吧!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 const int maxn = 50000+10;
 8 using namespace std;
 9 int a[maxn], n;
10 struct line
11 {
12     int l, r, val;
13 }tr[maxn<<2];
14
15 void build(int o, int l, int r)
16 {
17     tr[o].l = l; tr[o].r = r;
18     if(l == r)
19     {
20         tr[o].val = a[l];
21         return;
22     }
23     int mid = (l+r)>>1;
24     build(2*o, l, mid);
25     build(2*o+1, mid+1, r);
26     tr[o].val = tr[2*o].val+tr[2*o+1].val;
27 }
28 int query(int o, int l, int r)
29 {
30    if(tr[o].l==l && tr[o].r==r)
31    return tr[o].val;
32    int mid = (tr[o].l+tr[o].r)>>1;
33    if(r <= mid) query(2*o, l, r);
34    else if(l > mid) query(2*o+1, l, r);
35    else
36        return (query(2*o, l, mid)+query(2*o+1, mid+1, r));
37 }
38 void update(int o, int p, int add)
39 {
40     if(tr[o].l==tr[o].r&&tr[o].l==p)
41     {
42             tr[o].val += add;
43             return;
44     }
45     int mid = (tr[o].l+tr[o].r)>>1;
46     if(p<=mid) update(2*o, p, add);
47     else update(2*o+1, p, add);
48     tr[o].val = tr[2*o].val+tr[2*o+1].val;
49 }
50 int main()
51 {
52     int t, i, ca = 1;
53     int p, add, l, r;
54     char s[20];
55     scanf("%d", &t);
56     while(t--)
57     {
58         scanf("%d", &n);
59         for(i = 1; i <= n; i++)
60         scanf("%d", &a[i]);
61         printf("Case %d:\n", ca++);
62
63         build(1, 1, n);
64         while(~scanf("%s", s))
65         {
66             if(strcmp(s, "End")==0) break;
67             if(s[0]==‘Q‘)
68             {
69                 scanf("%d%d", &l, &r);
70                 printf("%d\n", query(1, l, r));
71             }
72             if(s[0]==‘A‘)
73             {
74                 scanf("%d%d", &p, &add);
75                 update(1, p, add);
76             }
77             if(s[0]==‘S‘)
78             {
79                 scanf("%d%d", &p, &add);
80                 update(1, p, -add);
81             }
82         }
83     }
84     return 0;
85 }

注释的代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 const int maxn = 50000+10;
 8 using namespace std;
 9 int a[maxn], n;
10 struct line
11 {
12     int l, r, val;   //val表示该区间的和
13 }tr[maxn<<2];
14
15 void build(int o, int l, int r) //o代表当前节点编号
16 {
17     tr[o].l = l; tr[o].r = r;
18     if(l == r)
19     {
20         tr[o].val = a[l];
21         return;
22     }
23     int mid = (l+r)>>1;
24     build(2*o, l, mid);
25     build(2*o+1, mid+1, r);
26     tr[o].val = tr[2*o].val+tr[2*o+1].val;  //建树把值从下往上加起来
27 }
28 int query(int o, int l, int r)  //求l到r的和
29 {
30    if(tr[o].l==l && tr[o].r==r) //节点的区间吻合返回
31    return tr[o].val;
32    int mid = (tr[o].l+tr[o].r)>>1;
33    if(r <= mid) query(2*o, l, r);
34    else if(l > mid) query(2*o+1, l, r);
35    else
36        return (query(2*o, l, mid)+query(2*o+1, mid+1, r)); //横跨了区间
37 }
38 void update(int o, int p, int add) //对p节点增加add
39 {
40     if(tr[o].l==tr[o].r&&tr[o].l==p)
41     {
42             tr[o].val += add;
43             return;
44     }
45     int mid = (tr[o].l+tr[o].r)>>1;
46     if(p<=mid) update(2*o, p, add);
47     else update(2*o+1, p, add);
48     tr[o].val = tr[2*o].val+tr[2*o+1].val;  //找到值以后的更新
49 }
50 int main()
51 {
52     int t, i, ca = 1;
53     int p, add, l, r;
54     char s[20];
55     scanf("%d", &t);
56     while(t--)
57     {
58         scanf("%d", &n);
59         for(i = 1; i <= n; i++)
60         scanf("%d", &a[i]);
61         printf("Case %d:\n", ca++);
62
63         build(1, 1, n);
64         while(~scanf("%s", s))
65         {
66             if(strcmp(s, "End")==0) break;
67             if(s[0]==‘Q‘)
68             {
69                 scanf("%d%d", &l, &r);
70                 printf("%d\n", query(1, l, r));
71             }
72             if(s[0]==‘A‘)
73             {
74                 scanf("%d%d", &p, &add);
75                 update(1, p, add);
76             }
77             if(s[0]==‘S‘)
78             {
79                 scanf("%d%d", &p, &add);
80                 update(1, p, -add);
81             }
82         }
83     }
84     return 0;
85 }

HDU 1166 敌兵布阵 (线段树 单点更新)

时间: 2024-08-24 04:13:52

HDU 1166 敌兵布阵 (线段树 单点更新)的相关文章

HDU 1166 敌兵布阵(线段树单点更新,板子题)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 87684    Accepted Submission(s): 36912 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

HDU 1166 敌兵布阵 //线段树单点更新

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 41385    Accepted Submission(s): 17489 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

HDU 1166 敌兵布阵 线段树单点更新求和

题目链接 中文题,线段树入门题,单点更新求和,建一棵树就可以了. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define N 50005 using namespace std; int data[N]; struct Tree { int l,r,sum; }tree[N*4]; void bui

【原创】hdu 1166 敌兵布阵(线段树→单点更新,区间查询)

学习线段树的第三天...真的是没学点啥好的,又是一道水题,纯模板,我个人觉得我的线段树模板还是不错的(毕竟我第一天相当于啥都没学...找了一整天模板,对比了好几个,终于找到了自己喜欢的类型),中文题目嘛,直接上代码 我感觉我的代码有一个特点吧...有点啰嗦,但是每一行的思维和上一行紧密相连,新手看的话不会感到思维的跃迁,比较容易看懂,因为我之前看一些大神的代码,确实看到一半就不知道他下面啥意思了...所以希望我的代码能够造福新手吧=.= 1 #include<cstdio> 2 #includ

hdu 1166 敌兵布阵 线段树 点更新

// hdu 1166 敌兵布阵 线段树 点更新 // // 这道题裸的线段树的点更新,直接写就可以了 // // 一直以来想要进线段树的坑,结果一直没有跳进去,今天算是跳进去吧, // 虽然十分简单,十分的水,继续加油 #include <algorithm> #include <bitset> #include <cassert> #include <cctype> #include <cfloat> #include <climits

HDU - 1166 敌兵布阵 (线段树+单点修改,区间查询和)

C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人,例如Derek问:“Tidy,马上汇

[HDU 1166 敌兵布阵] 线段树 或 树状数组

1 #include<iostream> 2 #include<cstdio> 3 #include<memory.h> 4 using namespace std; 5 int n,C[50005]; 6 //-------------------------- 7 int lowbit(int x){ 8 return x&-x; 9 } 10 int sum(int x){ 11 int ret=0; 12 while(x>0){ 13 ret+=C

HDU1166_敌兵布阵(线段树/单点更新)

解题报告 题意: 略 思路: 线段树单点增减和区间求和. #include <iostream> #include <cstring> #include <cstdio> #define LL long long using namespace std; int sum[201000]; void update(int root,int l,int r,int p,int v) { int mid=(l+r)/2; if(l==r)sum[root]+=v; else

HDU 1166 敌兵布阵 线段树

敌兵布阵 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视.中央情

hdu 1166 敌兵布阵 (线段树)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 45437    Accepted Submission(s): 19314 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务