题目描述:

问题描述
有n个格子,从左到右放成一排,编号为1-n。 共有m次操作,有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操作的结果。 样例输入 样例输出 数据规模与约定
对于20%的数据n <= ,m <= 。 对于50%的数据n <= ,m <= 。 对于100%的数据1 <= n <= ,m <= , <= 格子权值 <= 。

题目描述

代码如下:

 #include <stdio.h>
#define MAX(X,Y) (X)>(Y)?(X):(Y) struct node
{
int l,r,max,sum;
}a[]; //初始化线段树
void init(int l,int r,int index)
{
int mid;
a[index].l = l;
a[index].r = r;
a[index].max = ;
a[index].sum = ;
if (l != r)
{
mid = (l+r)/;
init(l,mid,*index);
init(mid+,r,*index+);
}
return ;
} //更新对应点的权值
void update(int old,int date,int index)
{
int mid;
if (old>=a[index].l && old<=a[index].r)//更新点所在区间的信息
{
a[index].max = date;//更新点所在区间的最大值
a[index].sum = date;//更新点所在区间的和
}
if (a[index].l == a[index].r)
return ; mid = (a[index].l + a[index].r)/;
if (old <= mid)
update(old,date,*index);
else
update(old,date,*index+); a[index].sum = a[*index].sum + a[*index+].sum;
a[index].max = MAX(a[*index].max,a[*index+].max);
return ;
} //查找区间的最大值
int find_max(int l,int r,int index)
{
int mid;
if (l==a[index].l && r==a[index].r)
return a[index].max; mid = (a[index].l + a[index].r)/;
if (l > mid)
return find_max(l,r,*index+);
else if (r <= mid)
return find_max(l,r,*index);
else
return MAX(find_max(l,mid,*index),find_max(mid+,r,*index+));
} //求区间和
int find_sum(int l,int r,int index)
{
int mid;
if (l==a[index].l && r==a[index].r)
return a[index].sum; mid = (a[index].l + a[index].r)/; if (l > mid)
return find_sum(l,r,*index+);
else if(r <= mid)
return find_sum(l,r,*index);
else
return find_sum(l,mid,*index)+find_sum(mid+,r,*index+);
} int main(void)
{
int i;
int n,m,date,x,y;
scanf("%d%d",&n,&m);
init(,n,);
for (i= ; i<=n ; i ++)
{
scanf("%d",&date);
update(i,date,);//将i替换为date
} while (m--)
{
scanf("%d%d%d",&date,&x,&y);
switch(date)
{
case :
update(x,y,);break;//将x替换为y
case :
printf("%d\n",find_sum(x,y,));break;//区间[x,y]的权值和
case :
printf("%d\n",find_max(x,y,));break;//区间[x,y]的最大权值
default:break;
}
} return ;
}

C解法

参考:https://blog.csdn.net/libin56842/article/details/19909975

线段树了解:https://www.cnblogs.com/AC-King/p/7789013.html

解题思路:

题目要求包括,1.权值替换;2.求区间和;求区间最大值

普通数组查询方法对于2,3问题会出现超时,故使用线段树

线段树类似二分查找,可大大缩短查找时间

线段树适用问题:

1.求区间数字和=左区间数字和+右区间数字和

2.最大公因数(GCD)=gcd(左区间gcd,右区间gcd)

3.最大值=max(左区间max,右区间max)

最新文章

  1. 微信小程序首次官方分享的纪要
  2. 1047: 小A的计算器
  3. 【UWP】不通过异常判断文件是否存在
  4. 转:Tomcat配置
  5. IOS7修改Navigation Bar上的返回按钮文本颜色,箭头颜色以及导航栏按钮的颜色
  6. c++中string类的具体解释
  7. Jquery table元素操作-创建|数据填充|重置|隐藏行
  8. Luogu3444:[POI2006]ORK-Ploughing
  9. 浅谈SSH框架
  10. JQuery显示,隐藏和淡入淡出效果
  11. 爬了招聘网站之后,总结Python学习的几点建议
  12. 1.Float精度在JS的解决方法
  13. Python3获取拉勾网招聘信息
  14. ie8 background背景图片不显示问题
  15. 五、UI开发之核心基础——约束(深入)
  16. js添加锚点
  17. 【Spark调优】:如果实在要shuffle,使用map侧预聚合的算子
  18. mysql8.0CTE实现递归查询
  19. 鸟哥的linux私房菜第4版--自学笔记
  20. Android :Activity、Adapter、List的初步学习

热门文章

  1. 用jq修改css
  2. 网络IP和网络掩码以及网关的学习
  3. 欧拉函数  已经优化到o(n)
  4. js添加select中option
  5. webpack中hash、chunkhash、contenthash区别
  6. git pull refusing to merge unrelated histories
  7. oracle修改字符集方法
  8. MySQL--使用innodb_force_recovery修复数据库异常
  9. day43 数据库学习egon的博客 视图、触发器、事务、存储过程、函数
  10. LDAP服务器的概念和原理简单介绍