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

基本上就是个简单的线段树的单点修改(update)与区间查询(query)连Lazy标记都不用

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

 

若是初学线段树 hdu1754也是道不错的题

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

题解的传送门:http://www.cnblogs.com/Donnie-Darko/p/4771062.html

附上代码(T1166)

 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 }

 

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

 

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

posted @ 2015-08-27 10:35  Donnie_Darko  阅读(136)  评论(0编辑  收藏  举报