hdu1166 线段树单点修改与区间查询

基本上就是个简单的线段树的单点修改(update)与区间查询(query)

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1166

连Lazy标记都不用

附上代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=50000+10;
 7 int n,m,i,j,T,a[maxn],sumt[maxn*4];
 8 char s[20];
 9 int max(int a,int b) {return a>b?a:b;}
10 int min(int a,int b) {return a<b?a:b;}
11 int abs(int a) {return a>0?a:-a;}
12 int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
13 void build(int node,int s,int t)
14 {
15      if (s==t){sumt[node]=a[s]; return;}
16      int mid=(s+t)/2,lson=2*node,rson=lson+1;
17      build(lson,s,mid);
18      build(rson,mid+1,t);
19      sumt[node]=sumt[lson]+sumt[rson];
20 }
21 void update(int node,int s,int t,int id,int add)
22 {
23      if (s==t){sumt[node]+=add; return;}
24      int mid=(s+t)/2,lson=2*node,rson=lson+1;
25      if (id<=mid) update(lson,s,mid,id,add);
26              else update(rson,mid+1,t,id,add);
27      sumt[node]=sumt[lson]+sumt[rson];
28 }
29 int query(int node,int s,int t,int L,int R)
30 {
31     if (t<L||R<s) return -1;
32     if (L<=s&&t<=R) return sumt[node];
33     int mid=(s+t)/2,lson=2*node,rson=lson+1;
34     int ansl,ansr;
35     ansl=query(lson,s,mid,L,R);
36     ansr=query(rson,mid+1,t,L,R);
37     if (ansl==-1) return ansr;
38     if (ansr==-1) return ansl;
39     return ansl+ansr;
40 }
41
42 int main()
43 {
44     scanf("%d",&T);
45     int T2=0;
46     while (T)
47     {
48           T--;
49           printf("Case %d:\n",++T2);
50           scanf("%d",&n);
51           for (i=1;i<=n;i++) scanf("%d",&a[i]);
52           build(1,1,n);
53           while (1)
54           {
55                 scanf("%s",s);
56                 if (s[0]==‘E‘) break;
57                 scanf("%d%d",&i,&j);
58                 if (s[0]==‘A‘) update(1,1,n,i,j);
59                 if (s[0]==‘S‘) update(1,1,n,i,-j);
60                 if (s[0]==‘Q‘) printf("%d\n",query(1,1,n,i,j));
61           }
62     }
63 }

顺便,这里有一个线段树模板(无Lazy标记的)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6
 7 const int maxn=50000+10;
 8 int n,m,i,j,a[maxn];
 9 int max(int a,int b) {return a>b?a:b;}
10 int min(int a,int b) {return a<b?a:b;}
11
12 int mint[maxn*4],maxt[maxn*4],sumt[maxn*4];
13 void outp(int node,int s,int t)//这个函数可以在调试的时候用
14 {
15      printf("\%d<------>%d\n",s,t);
16      int mid=(s+t)/2,lson=2*node,rson=lson+1;
17      printf("min=%d max=%d\n",mint[node],maxt[node]);
18      printf("sum=%d\n",sumt[node]);
19      if (s==t) return;
20      outp(lson,s,mid);
21      outp(rson,mid+1,t);
22      mint[node]=min(mint[lson],mint[rson]);
23      maxt[node]=max(maxt[lson],maxt[rson]);
24      sumt[node]=sumt[lson]+sumt[rson];
25 }
26 void build(int node,int s,int t)
27 {
28      if (s==t)
29      {
30          sumt[node]=a[s];
31          mint[node]=a[s];
32          maxt[node]=a[s];
33          return;
34      }
35      int mid=(s+t)/2,lson=2*node,rson=lson+1;
36      build(lson,s,mid);
37      build(rson,mid+1,t);
38      mint[node]=min(mint[lson],mint[rson]);
39      maxt[node]=max(maxt[lson],maxt[rson]);
40      sumt[node]=sumt[lson]+sumt[rson];
41 }
42 void update(int node,int s,int t,int id,int add)
43 {
44      if (s==t)
45      {
46          sumt[node]+=add;
47          mint[node]+=add;
48          maxt[node]+=add;
49          return;
50      }
51      int mid=(s+t)/2,lson=2*node,rson=lson+1;
52      if (id<=mid) update(lson,s,mid,id,add);
53              else update(rson,mid+1,t,id,add);
54      mint[node]=min(mint[lson],mint[rson]);
55      maxt[node]=max(maxt[lson],maxt[rson]);
56      sumt[node]=sumt[lson]+sumt[rson];
57 }
58 int query(int node,int s,int t,int L,int R)
59 {
60     if (t<L||R<s) return -1;
61     if (L<=s&&t<=R) return sumt[node];//mint[node] maxt[node]
62     int mid=(s+t)/2,lson=2*node,rson=lson+1;
63     int ansl,ansr;
64     ansl=query(lson,s,mid,L,R);
65     ansr=query(rson,mid+1,t,L,R);
66     if (ansl==-1) return ansr;
67     if (ansr==-1) return ansl;
68     return ansl+ansr;//min(ansl,ansr) max(ansl,ansr)
69 }

比较简陋,只支持区间求和,区间最大最小值

还望大神不吝赐教,斧正斧正

时间: 2024-10-29 05:17:22

hdu1166 线段树单点修改与区间查询的相关文章

【模板】线段树-单点修改,区间查询

容易理解但是难打(又长又难调)------仅代表个人观点 (能别打就别打) 线段树是什么? 大概长这样?(表示区间1到6) 线段树是一颗二叉树,是通过二分思想建立的一颗表示区间关系的树形结构.(总之记住它很好用就对了) 怎样建一颗线段树 大概思路: 二分+递归 没什么好讲的,具体看代码吧.. //建树 struct node { int a,b; }tree[100001]; void make_tree(int p,int x,int y)//p为当前节点编号,x,y为区间的左右端点 { tr

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

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

ZOJ 3632 Watermelon Full of Water(dp+线段树 单点修改)

题意: 一共有n天 每天西瓜售价为dp[i]元 该天的西瓜能吃v[i]天 而且这天如果买了西瓜之前的西瓜就要扔掉 问每天都吃到西瓜的最小花费是多少 思路: 从最后一天开始dp最小花费 并用线段树单点更新来维护 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; #define ll long long #def

HDU 1754 I Hate It 【线段树单点修改 区间查询】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 102825    Accepted Submission(s): 38669 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,

数据结构--M - 秋实大哥与线段树(单点更新与区间查询)

M - 秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status “学习本无底,前进莫徬徨.” 秋实大哥对一旁玩手机的学弟说道. 秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构. 为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作. 秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值:一

敌兵布阵 HDU - 1166 (线段树单点修改)

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

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

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

hdu 5480 Conturbatio 线段树 单点更新,区间查询最小值

Conturbatio Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5480 Description There are many rook on a chessboard, a rook can attack the row and column it belongs, including its own place. There are also many quer

线段树单点修改、区间修改、单点查询值、区间查询最大值、最小值、区间和之模板

毕生所学. 1 const int N = 2e5 + 10; 2 #define lson rt << 1 // == rt * 2 左儿子 3 #define rson rt << 1 | 1 // == rt * 2 + 1 右儿子 4 #define int_mid int mid = tree[rt].l + tree[rt].r >> 1 5 int a[N]; // 初始值 6 struct node { 7 int l, r; 8 ll val, laz