线段树超级大模版

建树

void build(int o,int l,int r)   //o:当前建立的节点 l:左端点  r:右端点
{
    if(l == r)                  //建立叶子信息
        st[o] = a[l];
    else
    {
        int m = l + ((r-l) >> 1);   // m 为中间点,左儿子结点为 [l,m] ,右儿子结点为 [m+1,r];
        build(o << 1,l,m);          //构建左儿子结点
        build((o<<1)|1,m+1,r);      //构建右儿子结点
        st[o] = max(st[o << 1],st[(o<<1)|1]);   //递归返回时用儿子结点更新父节点,此处可进行更新最大值、最小值、区间和等操作
    }
}

 build(1, 1, n);//主函数里的语句

单点修改

void update(int o,int l,int r,int ind,int ans)  //o、l、r为当前更新到的结点、左右端点,ind为需要修改的叶子结点左端点,ans为需要修改成的值;
{
    if(l == r)      //若当前更新点的左右端点相等即到叶子结点时,直接更新信息并返回
    {
        st[o] = ans;
        return ;
    }
    int m = l + ((r-l) >> 1);
    if(ind <= m)
        update(o << 1,l,m,ind,ans);
    else
        update((o<<1)|1,m+1,r,ind,ans);
    st[o] = max(st[o<<1],st[(o<<1)|1]);     //递归回之后用儿子结点更新父节点(此处是区间最大值)也可以是最小值或者是区间和
}

 update(1, 1, n, a, b);//在主函数里的语句

区间查询

int query(int o,int l,int r,int ql,int qr)      //ql、qr为需要查询的区间左右端点
{
    if(ql > r || qr < l)    //若当前结点和需要查找的区间不相交,则返回一个对于区间查询无关的值(如求和时返回0,求最大值时返回-1等)
        return -1;
    if(ql <=l && qr >=r)    //若当前结点的区间被需要查询的区间覆盖,则返回当前结点的信息
        return st[o];
    int m = l + ((r-l) >> 1);
    int p1 = query(o<<1,l,m,ql,qr);     //p1为查询左儿子结点得到的信息,p2为查询右儿子结点得到的信息
    int p2 = query((o<<1)|1,m+1,r,ql,qr);
    return max(p1,p2);      //综合两个儿子结点的信息并返回
}

query(1, 1, n, a, b)//主函数里的查询语句

原文地址:https://www.cnblogs.com/smallhester/p/10498731.html

时间: 2024-10-17 10:21:23

线段树超级大模版的相关文章

线段树(大三的模板)

Up函数 用来更新父亲节点的值 void push(int w) { sum[w] = sum[2*w]+sum[2*w+1];//更新节点值 } 单点更新 先找出第p个数 然后更新他的值 void add(int p,int d,int l,int r,int w) { if(l==r) { sum[w]+=d; return ; } int m = (l+r)/2; if(p<=m) add(p,d,l,m,2*w); else add(p,d,m+1,r,2*w+1); push(w);

线段树 大根堆 模版二合一

#include "stdafx.h" #include <cstdio> #include <iostream> #include <algorithm> #define N 2000001 using namespace std; inline void read_int(int &now_); class T_heap { private: int heap[N], num; public: void up(int now) { if

线段树 区间更新 模版

#include <iostream> #include"cstdio" #include"string.h" using namespace std; const int N= 100005; struct node { int left; int right; int add; int sum; } tree[N*4]; int n,m; int a[N]; void init() { memset(tree,0,sizeof(tree)); mem

线段树专题(一)

Acmer可怜啊,根本没有休息,昨天才刚刚完成了矩阵专题,今天又要开线段树专题了.唉,等我以后月薪15K的时候,我要好好享受人生......呃,扯远了.线段树是一个非常重要的数据结构,以前就学习过,但是没有系统的刷过难题,这次我决定将kuangbin先生的专题和NotOnlySuccess大神的专题一起刷掉.因为题目多又难,所以分成几个部分(最多三个把). 对于线段树的话,主要是理解它的树形结构吧,推荐和树状数组一起学习.似乎树状数组就是线段树的退化,树状数组节约了差不多一半的空间,但是必须满足

2017 ACM-ICPC 北京网络赛 Minimum 线段树

描述 You are given a list of integers a0, a1, -, a2^k-1. You need to support two types of queries: 1. Output Minx,y∈[l,r] {ax?ay}. 2. Let ax=y. 输入 The first line is an integer T, indicating the number of test cases. (1≤T≤10). For each test case: The fi

线段树复习打卡——1318: 借教室

http://61.139.95.227:82/problem.php?id=1318 线段树区间修改模版 #include <bits/stdc++.h> #define read read() #define up(i,l,r) for(int i = (l);i <= (r);i++) #define down(i,l,r) for(int i = (l);i >= (r);i--) #define ll long long #define lson l,mid,rt<

poj2104 求区间第k大 可持久化线段树

poj2104 求区间第k大  可持久化线段树 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef

zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 Description The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query l

HDU 4417 Super Mario ( 超级马里奥 + 主席树 + 线段树/树状数组离线处理 + 划分树 )

HDU 4417 - Super Mario ( 主席树 + 线段树/树状数组离线处理 + 划分树 ) 这道题有很多种做法,我先学习的是主席树.后面陆续补上线段树离线和划分树 题目大意就是给定一个区间给定一个数列,每次要求你查询区间[L,R]内不超过K的数的数量 主席树做法: 最基本的是静态第k大,这里是求静态的 <= K,差不多,在Query操作里面需要修改修改 先建立size棵主席树,然后询问的时候统计的是 第R棵主席树中[1,K]的数量 - 第L-1棵主席树中[1,K]的数量 注意这里下标