模板 - 数据结构 - 线段树(单点修改)

这里是以区间最大值为例,要修改成其他的运算,注意修改每个函数的运算以及query中返回的无关值

这里的区间最大值设置的最小元素为-1(在query中表示与当前区间不相交的区间的结果)。

注意因为调用的方式传入l与r是(1,n),所以这个线段树(包括a)其实是从1开始计数的。

最后,小心爆MAXM

const int MAXM=200000;
int a[MAXM+5],st[(MAXM<<2)+5];

void build(int o,int l,int r){
    if(l==r) st[o]=a[l];
    else{
        int m=l+((r-l)>>1);
        build(o<<1,l,m);
        build(o<<1|1,m+1,r);
        st[o]=max(st[o<<1],st[o<<1|1]);
    }
}

void update(int o,int l,int r,int id,int v){
    if(l==r) st[o]=v;
    else{
        int m=l+((r-l)>>1);
        if(id<=m) update(o<<1,l,m,id,v);
        else update(o<<1|1,m+1,r,id,v);
        st[o]=max(st[o<<1],st[o<<1|1]);
    }
}

int query(int o,int l,int r,int a,int b){
    if(r<a||l>b) return -1;
    if(a<=l&&r<=b) return st[o];
    int m=l+((r-l)>>1);
    int p1=query(o<<1,l,m,a,b),p2=query(o<<1|1,m+1,r,a,b);
    return max(p1,p2);
}

原文地址:https://www.cnblogs.com/Yinku/p/10318874.html

时间: 2024-11-06 05:24:32

模板 - 数据结构 - 线段树(单点修改)的相关文章

【模板】线段树-单点修改,区间查询

容易理解但是难打(又长又难调)------仅代表个人观点 (能别打就别打) 线段树是什么? 大概长这样?(表示区间1到6) 线段树是一颗二叉树,是通过二分思想建立的一颗表示区间关系的树形结构.(总之记住它很好用就对了) 怎样建一颗线段树 大概思路: 二分+递归 没什么好讲的,具体看代码吧.. //建树 struct node { int a,b; }tree[100001]; void make_tree(int p,int x,int y)//p为当前节点编号,x,y为区间的左右端点 { tr

【模板】线段树区间修改

区间修改: 区间修改过程类似于区间询问,例如将[ul, ur]内的所有元素都加上v,则进行如下操作: 当当前区间被区间[ul, ur]所包含时, 当前的节点值加上区间长度(r - l  + 1)乘以v 对当前节点的lazy-tag加上v,修改结束 否则,将当前节点的lazy-tag下传,分别修改左孩子和右孩子(一定条件下),然后更新此节点的值 lazy-tag下传: 如果当前节点没有lazy-tag,直接return 否则:1. 将左孩子右孩子分别加上lazy-tag * 区间长度的值  2.

ZOJ 3632 Watermelon Full of Water(dp+线段树 单点修改)

题意: 一共有n天 每天西瓜售价为dp[i]元 该天的西瓜能吃v[i]天 而且这天如果买了西瓜之前的西瓜就要扔掉 问每天都吃到西瓜的最小花费是多少 思路: 从最后一天开始dp最小花费 并用线段树单点更新来维护 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; #define ll long long #def

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

基本上就是个简单的线段树的单点修改(update)与区间查询(query) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1166 连Lazy标记都不用 附上代码 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=50000+1

敌兵布阵 HDU - 1166 (线段树单点修改)

敌兵布阵 HDU - 1166 题目链接:https://vjudge.net/problem/HDU-1166 题目: C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人

HDU 1754 I Hate It 【线段树单点修改 区间查询】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 102825    Accepted Submission(s): 38669 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,

HDU - 1166 敌兵布阵 (线段树+单点修改,区间查询和)

C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人,例如Derek问:“Tidy,马上汇

线段树单点修改、区间修改、单点查询值、区间查询最大值、最小值、区间和之模板

毕生所学. 1 const int N = 2e5 + 10; 2 #define lson rt << 1 // == rt * 2 左儿子 3 #define rson rt << 1 | 1 // == rt * 2 + 1 右儿子 4 #define int_mid int mid = tree[rt].l + tree[rt].r >> 1 5 int a[N]; // 初始值 6 struct node { 7 int l, r; 8 ll val, laz

树链剖分+线段树 单点修改 区间求和 模板

马上要去西安打邀请赛了,存下板子 首先是vector存图的: #include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 const int M = 2e5+10; int fa[M],dep[M],siz[M],son[M