今天学习了线段树的三个基本操作 建树 更新 查找

先理解下什么是线段树
就这个题目而言 如果我们用普通的数组去存放 然后依次遍历访问的话 时间太多了
线段树利用了二分的思想 把数据以段的形式进行储存 这样在访问的时候 时间复杂度就下来了

上图就是线段树的一个简单的模型

创建线段树(初始化)】:

由于线段树是用二叉树结构储存的,而且是近乎完全二叉树的,所以在这里我使用了数组来代替链表上图中区间上面的红色数字表示了结构体数组中对应的下标。

在完全二叉树中假如一个结点的序号(数组下标)为 I ,那么 (二叉树基本关系)

I 的父亲为 I/2,

I 的另一个兄弟为 I/2*2 或 I/2*2+1

I 的两个孩子为 I*2 (左)   I*2+1(右)

这段来自其他同学的博客  这个是建树的基础 我们用标号来链接每个叶节点

struct node
{
int maxx;
int l,r;
}stu[maxn*4]; 这个结构体就是每一个线段树的一个叶 其中有左右节点以及本题需要的max值
先说说建树操作把
int mid=(l+r)/2;
stu[i].l=l;
stu[i].r=r;
既然利用到了二分的思想 那么 这几步是少不了的
  
void buildtree(int i,int l,int r)//建树
{
int mid=(l+r)/2;
stu[i].l=l;
stu[i].r=r;
if(l==r)
{
stu[i].maxx=a[l];
return;
}
buildtree(i*2,l,mid);//构建左子点
buildtree(i*2+1,mid+1,r);//构建右子点
stu[i].maxx=max(stu[i*2].maxx,stu[i*2+1].maxx);//在递归结束回溯的时候 把最大值返回
}
再说说数据的更新
更新的话 先得二分找到目标位置 然后替换 最后还得依次更新最大值的数据
void updata(int i)//更新
{
int l=stu[i].l;
int r=stu[i].r;
int mid=(l+r)/2;//二分咯
if(l==r&&r==x)//x为目标id 当左右节点相同的时候 就是找到这个数的时候
{
stu[i].maxx=y;
return;
}
if(l<=x&&x<=mid) updata(i*2);//向左找
else updata(i*2+1);//向右找
stu[i].maxx=max(stu[i*2].maxx,stu[i*2+1].maxx);//回溯的时候 更新max的数据
}
最后就是询问过程了
找最大值的过程中 要把要求的区间分段 即分割成好几个小段 然后放在建好的书里面找
int que(int a,int b,int i)//查找
{
int l=stu[i].l;
int r=stu[i].r;
int mid=(l+r)/2;
if(l==a&&r==b) return stu[i].maxx;
if(b<=mid) return que(a,b,i*2);//全在右边
else if(a>mid) return que(a,b,i*2+1);//全在左边
else return max(que(a,mid,i*2),que(mid+1,b,i*2+1));//需要分割的话 取分开的最大
}
上完整代码
#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
#define maxn 200010
struct node
{
int maxx;
int l,r;
}stu[maxn*4];
int a[maxn];
int n,m,x,y;
void buildtree(int i,int l,int r)//建树
{
int mid=(l+r)/2;
stu[i].l=l;
stu[i].r=r;
if(l==r)
{
stu[i].maxx=a[l];
return;
}
buildtree(i*2,l,mid);
buildtree(i*2+1,mid+1,r);
stu[i].maxx=max(stu[i*2].maxx,stu[i*2+1].maxx);
}
void updata(int i)//更新
{
int l=stu[i].l;
int r=stu[i].r;
int mid=(l+r)/2;
if(l==r&&r==x)
{
stu[i].maxx=y;
return;
}
if(l<=x&&x<=mid) updata(i*2);
else updata(i*2+1);
stu[i].maxx=max(stu[i*2].maxx,stu[i*2+1].maxx);
}
int que(int a,int b,int i)//查找
{
int l=stu[i].l;
int r=stu[i].r;
int mid=(l+r)/2;
if(l==a&&r==b) return stu[i].maxx;
if(b<=mid) return que(a,b,i*2);
else if(a>mid) return que(a,b,i*2+1);
else return max(que(a,mid,i*2),que(mid+1,b,i*2+1));
}
int main()
{
char z;
cin.sync_with_stdio(false);
while(cin>>n>>m)
{
for(int i=1;i<=n;i++) cin>>a[i];
buildtree(1,1,n);
while(m--)
{
cin>>z>>x>>y;
if(z=='U')
{
updata(1);
}
else
{ cout<<que(x,y,1)<<endl;
}
}
}
return 0;
}

入手线段树 hdu1754的更多相关文章

  1. [线段树]HDU-1754板子题入门ver

    HDU-1754 线段树数组请开到四倍 众所周知数组开小会导致re tle wa等一系列问题orz 板子就是板子,数组从零开始或是从一开始都没什么问题,就是2*root+1还是2*root+2的问题. ...

  2. 线段树---HDU1754 I hate it

    这个题也是线段树的基础题,有了上一个题的基础,在做这个题就显得比较轻松了,大体都是一样的,那个是求和,这个改成求最大值,基本上思路差不多,下面是代码的实现 #include <cstdio> ...

  3. 线段树 HDU-1754 I Hate It

    附上原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某 ...

  4. 线段树hdu1754

    #include<iostream>#include<stdio.h>using namespace std;const int maxa=200005;int val[max ...

  5. 几道简单的线段树入门题 POJ3264&&POJ3468&&POJ2777

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 40687   Accepted: 19137 ...

  6. I Hate It(hdu1754)(线段树区间最大值)

    I Hate It hdu1754 Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. HDU1754 && HDU1166 线段树模板题

    HDU1754 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题目分析:对于给出的一个很长的区间,对其进行单点更新值和区间求最大值的操作,由于 ...

  8. HDU1166(线段树 +更新单点,求区间总和)、HDU1754(线段树 + 更新单点,求区间最大值)

    线段树简单应用 先附上几张图便与理解,大佬文章传送门1.传送门2 HDU1166:题目描述 线段树 +更新单点,求区间总和 代码如下(递归版) #include<iostream> #in ...

  9. hdu1754 I hate it线段树模板 区间最值查询

    题目链接:这道题是线段树,树状数组最基础的问题 两种分类方式:按照更新对象和查询对象 单点更新,区间查询; 区间更新,单点查询; 按照整体维护的对象: 维护前缀和; 维护区间最值. 线段树模板代码 # ...

随机推荐

  1. ngx.shared.DICT.expire 详解

    ngx.shared.DICT.expire 原文链接: ngx.shared.DICT.expire syntax: success, err = ngx.shared.DICT:expire(ke ...

  2. Matrix: android 中的Matrix (android.graphics.Matrix) (转)

    本篇博客主要讲解一下如何处理对一个Bitmap对象进行处理,包括:缩放.旋转.位移.倾斜等.在最后将以一个简单的Demo来演示图片特效的变换. 1. Matrix概述 对于一个图片变换的处理,需要Ma ...

  3. SQL-W3School-函数:SQL MID() 函数

    ylbtech-SQL-W3School-函数:SQL MID() 函数 1.返回顶部 1. MID() 函数 MID 函数用于从文本字段中提取字符. SQL MID() 语法 SELECT MID( ...

  4. Win10系统安装VMware-viclient-6.0无响应问题解决方法

    背景:笔记本重做系统升级至Win10系统后,由于工作需要,得安装VMware-viclient-6.0软件进行远程连接. 问题:没有出现网上那种各种报错情况,只是在点击“安装”按钮的时候没弹出任何等待 ...

  5. Linux下设置Tomcat开机自启动

    --未验证 第一步:在/etc/init.d下新建一个文件tomcat(需要root操作权限) vi /etc/init.d/tomcat 然后点击"i"写下如下代码,tomcat ...

  6. pytorch0.4.1安装

    pytorch官网:https://pytorch.org/ 这里安装pytorch0.4.1版本(最新版本为1.3.0系列,但是在跑github上的一些项目时会不断地报“ UseWarinig:Le ...

  7. 35个高级Python知识点总结

    原文地址:https://blog.51cto.com/xvjunjie/2156525 No.1 一切皆对象 众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底, ...

  8. git推送远程仓库以及分支介绍

    1.介绍 我们要把本地仓库的项目推送到远程服务器,首先我们得有自己的服务器,一般我们选择码云和github,码云和github的操作差不多,今天我们再次介绍码云的使用 2.码云的使用 第一步:首先我们 ...

  9. 居里先生的猜想 | 皮埃尔·居里诞辰160周年

    皮埃尔·居里(Pierre Curie)先生坐在桌前,手里把玩着一块小磁铁.忽然,一道闪念跃入脑海,他为自己这个大胆的想法激动不已,忍不住伏案疾笔书写起来.不远处,一位安静的青年女子温情脉脉地注视着他 ...

  10. git 命令使用

    //快速删除node_modules: 1.npm install -g rimraf  2. rimraf node_modules 1.本地新建分支并且连接远端 克隆:git clone 远端地址 ...