线段树、树状数组入门

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-27 19:09:30

HDU-1166

思路:更新区间,结构体内保存最大值

 1 #include<stdio.h>
 2 #include<string>
 3 #include<iostream>
 4 using namespace std;
 5 const int MAXN = 5e4+5;
 6 int a[MAXN];
 7 struct node
 8 {
 9     int L,R,sum,la;
10 }tree[MAXN<<2];
11 //建树 
12 void Build(int L,int R,int step)
13 {
14     tree[step].L=L;tree[step].R=R;
15     if(L==R)
16     {
17         tree[step].sum=a[L];return;
18     }
19     int mid=(L+R)>>1;
20     Build(L,mid,step<<1);
21     Build(mid+1,R,step<<1|1);
22     tree[step].sum=tree[step<<1].sum+tree[step<<1|1].sum;
23 }
24 //单点查询
25 int Query(int P,int step)
26 {
27     if(tree[step].L==tree[step].R)return tree[step].sum;
28     int mid=(tree[step].L+tree[step].R)>>1;
29     int ans;
30     if(P<=mid)ans=Query(P,step<<1);
31     else Query(P,step<<1|1);
32     return ans;    
33 } 
34 //单点修改
35 void Add(int P,int val,int step)
36 {
37     if(tree[step].L==tree[step].R)
38     {
39         tree[step].sum+=val;return ;
40     }
41     int mid=(tree[step].L+tree[step].R)>>1;
42     if(P<=mid)Add(P,val,step<<1);
43     else Add(P,val,step<<1|1);
44     tree[step].sum=tree[step<<1].sum+tree[step<<1|1].sum;
45  } 
46 //区间查询
47 int Ask(int L,int R,int step)
48 {
49     if(tree[step].L==L&&tree[step].R==R)return tree[step].sum;
50     int mid=(tree[step].L+tree[step].R)>>1;
51     if(R<=mid)return Ask(L,R,step<<1);
52     if(L>mid)return Ask(L,R,step<<1|1);
53     else return Ask(L,mid,step<<1)+Ask(mid+1,R,step<<1|1);    
54 } 
55 int main()
56 {
57     int T,K=1;
58     scanf("%d",&T);
59     while(T--)
60     {
61         int N;
62         scanf("%d",&N);
63         printf("Case %d:\n",K++);
64         for(int i=1;i<=N;++i)scanf("%d",&a[i]);
65         Build(1,N,1);
66         string s;
67         while(cin>>s)
68         {
69             if(s[0]=='E')break;
70             if(s[0]=='Q')
71             {
72                 int l,r;
73                 scanf("%d%d",&l,&r);
74                 printf("%d\n",Ask(l,r,1));
75             }
76             else
77             {
78                 int P,val;
79                 scanf("%d%d",&P,&val);
80                 if(s[0]=='S')val=-val;
81                 Add(P,val,1);
82             }
83         }
84     }
85     return 0;
86 } 

HDU-1754

思路:线段树模板题,更新单点区间,并且区间内保存最大值

 1 #include<stdio.h>
 2 #include<string>
 3 #include<iostream>
 4 using namespace std;
 5 const int MAXN = 2e5+5;
 6 int a[MAXN];
 7 struct node
 8 {
 9     int L,R,sum,la;
10 }tree[MAXN<<2];
11 int max(int a,int b)
12 {
13     return a>b?a:b;
14 }
15 //建树 
16 void Build(int L,int R,int step)
17 {
18     tree[step].L=L;tree[step].R=R;
19     if(L==R)
20     {
21         tree[step].sum=a[L];return;
22     }
23     int mid=(L+R)>>1;
24     Build(L,mid,step<<1);
25     Build(mid+1,R,step<<1|1);
26     tree[step].sum=max(tree[step<<1].sum,tree[step<<1|1].sum);
27 }
28 //单点修改
29 void Add(int P,int val,int step)
30 {
31     if(tree[step].L==tree[step].R)
32     {
33         tree[step].sum=val;return ;
34     }
35     int mid=(tree[step].L+tree[step].R)>>1;
36     if(P<=mid)Add(P,val,step<<1);
37     else Add(P,val,step<<1|1);
38     tree[step].sum=max(tree[step<<1].sum,tree[step<<1|1].sum);
39  } 
40 //区间查询
41 int Ask(int L,int R,int step)
42 {
43     if(tree[step].L==L&&tree[step].R==R)return tree[step].sum;
44     int mid=(tree[step].L+tree[step].R)>>1;
45     if(R<=mid)return Ask(L,R,step<<1);
46     if(L>mid)return Ask(L,R,step<<1|1);
47     else return max(Ask(L,mid,step<<1),Ask(mid+1,R,step<<1|1));    
48 } 
49 int main()
50 {
51     int N,T;
52     while(~scanf("%d%d",&N,&T))
53     {
54         for(int i=1;i<=N;i++)scanf("%d",&a[i]);
55         Build(1,N,1);
56         while(T--)
57         {
58             string s;
59             cin>>s;
60             int l,r;
61             scanf("%d%d",&l,&r);
62             if(s[0]=='Q')
63             {
64                 printf("%d\n",Ask(l,r,1));
65             }
66             else 
67             {
68                 Add(l,r,1);
69             }
70         }         
71     }
72     return 0;
73 } 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!