蓝桥杯 操作格子 基础线段树

问题描述

有n个格子,从左到右放成一排,编号为1-n。

共有m次操作,有3种操作类型:

1.修改一个格子的权值,

2.求连续一段格子权值和,

3.求连续一段格子的最大值。

对于每个2、3操作输出你所求出的结果。

输入格式

第一行2个整数n,m。

接下来一行n个整数表示n个格子的初始权值。

接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。

输出格式

有若干行,行数等于p=2或3的操作总数。

每行1个整数,对应了每个p=2或3操作的结果。

样例输入
4 3
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
数据规模与约定

对于20%的数据n <= 100,m <= 200。

对于50%的数据n <= 5000,m <= 5000。

对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。

【线段树】 好久没写线段树了  不过这次写的还蛮顺  主要是题目很简单

 
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 struct node{int l;int r;int maxx;int sum;}tree[1000000];
 6 
 7 void build(int l,int r,int x)
 8 {
 9     tree[x].l=l;
10     tree[x].r=r;
11     tree[x].maxx=0;
12     tree[x].sum=0;
13     if(l!=r)
14     {
15         int mid;  mid=(l+r)/2;
16         build(l,mid,x*2);
17         build(mid+1,r,x*2+1);
18     }
19 }
20 
21 void insert(int x,int k,int num)   //x 当前   k位置
22 {
23     if(tree[x].l==k&&tree[x].r==k)
24     {
25         tree[x].sum=num;
26         tree[x].maxx=num;
27         return ;
28     }
29     int mid;
30     mid=(tree[x].l+tree[x].r)/2;
31     if(k<=mid)
32         insert(x*2,k,num);
33     else insert(x*2+1,k,num);
34     tree[x].maxx=max(tree[x*2].maxx,tree[x*2+1].maxx);
35     tree[x].sum=tree[x*2].sum+tree[x*2+1].sum;
36 }
37 
38 int getsum(int x,int l,int r)
39 {
40     if(tree[x].l==l&&tree[x].r==r)
41         return tree[x].sum;
42     int mid;
43     mid=(tree[x].l+tree[x].r)/2;
44     if(r<=mid)
45         return getsum(x*2,l,r);
46     else if(l>mid)
47         return getsum(x*2+1,l,r);
48     return getsum(x*2,l,mid)+getsum(x*2+1,mid+1,r);
49 }
50 
51 int getmaxx(int x,int l,int r)
52 {
53     if(tree[x].l==l&&tree[x].r==r)
54         return tree[x].maxx;
55     int mid;
56     mid=(tree[x].l+tree[x].r)/2;
57     if(r<=mid)
58         return getmaxx(x*2,l,r);
59     if(l>mid)
60         return getmaxx(x*2+1,l,r);
61     return max(getmaxx(x*2,l,mid),getmaxx(x*2+1,mid+1,r));
62 
63 }
64 
65 
66 int main()
67 {
68     int n,m,p,a,b,x;
69     while(~scanf("%d%d",&n,&m))
70     {
71         build(1,n,1);
72         for(int i=1;i<=n;i++)
73         {
74             scanf("%d",&x);
75             insert(1,i,x);//printf("  &   ");
76         }
77         for(int i=0;i<m;i++)
78         {
79             scanf("%d%d%d",&p,&a,&b);
80             if(p==1)
81                 insert(1,a,b);
82             if(p==2)
83                     printf("%d
",getsum(1,a,b));//输出
84             if(p==3)
85                     printf("%d
",getmaxx(1,a,b));
86         }
87     }
88     return 0;
89 }
原文地址:https://www.cnblogs.com/assult/p/3614608.html