高级数据结构-线段树

1.模板(以维护最小值为例)

#include<iostream>
#include<stdio.h>

#define LEN 11
#define MAX 1<<30

using namespace std;

int arr[LEN]={1,3,7,6,8,5,3,2,7,2,9};
int st[LEN*3];    //segment tree
int n;

void init(int len){
    n=1;
    while(n<len) n*=2;    //不断乘以2,知道>=len
    for(int i=0;i<n;i++) st[i]=MAX;
}

void update(int p,int v){    //我们有n(len的二次幂扩增)个叶子作为线段元素
    p+=n-1;            //地址重定向,变为叶子节点所在地址
    st[p]=v;
    while(p>0){
        p=(p-1)/2;    //向上跳转到父节点
        st[p]=min(st[p*2+1],st[p*2+2]);    //更新父节点
    }
}

//    查询[a,b)的最小值,当前函数的查询是[l,r) 。当前根节点为p
int query(int a,int b,int p,int l,int r){//外部调用: query(a,b,0,0,n)
    //如果[a,b)与[l,r)不相交
    if(a>=r || b<=l)
        return MAX;
    //如果[a,b)包裹住了[l,r)
    if(a<=l && b>=r)
        return st[p];
    //其他情况,二分进行查询
    int v1=query(a,b,p*2+1,l,(l+r)/2);
    int v2=query(a,b,p*2+2,(l+r)/2,r);
    return min(v1,v2);
} 

int main(){
    init(LEN);
    int i,a,b;
    for(i=0;i<LEN;i++)
        update(i,arr[i]);
    while(1){
        scanf("%d%d",&a,&b);
        printf("%d\n",query(a,b,0,0,n));
    }
    return 0;
} 

2.POJ Crane

原文地址:https://www.cnblogs.com/TQCAI/p/8449528.html

时间: 2024-10-30 05:12:05

高级数据结构-线段树的相关文章

HDU 4902 Nice boat(数据结构-线段树)

Nice boat Problem Description There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and c

Chapter 3. 数据结构 线段树

Chapter 3. 数据结构 线段树 Sylvia's I.单点修改,区间查询. 模板: //单点修改 区间求和 //1操作 单点修改//2操作 区间求和 #include<cstdio> #include<iostream> using namespace std; #define MAXN 500005 int sum[MAXN<<2]; int n,m; void PushUp(int rt){//求和 sum[rt]=sum[rt<<1]+sum[

HDU 1394 Minimum Inversion Number (数据结构-线段树)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9514    Accepted Submission(s): 5860 Problem Description The inversion number of a given number sequence a1, a2, ..., an

比较高级的线段树

一.动态开点线段树 为什么要搞这样的一个鬼畜线段树? 1.区间范围过大,但是只会用到一些特定的节点,暴力开会爆内存 2.要开多棵线段树,考虑会内存爆炸,也只建需要用的节点 这个线段树的唯一区别就是需要记录下左儿子和右儿子的编号 二.主席树(可持久化线段树) First: 主席树的来源: 一个名叫主席的神犇发明的数据结构... Second: 主席树的作用: 可以实现查询单调递增的序列的特征值,拥有继承的能力,但是不能支持修改操作... Third: 主席树的思想: 适用于区间线段树大部分相同的情

不可能数据结构(线段树+思维+找规律)

不可能数据结构 Description造一道数据结构题是一件很累的事情.即使是有了坚固的数据结构造题程式,出题人仍然不能够一劳永逸.问题大概出在,造题程式并不总能生成对的题.比如,造题程式无意产生了一道出题人认为不可做题,这便成了一道错题.嘛,出了错题,其实也是没有关系的.出题人可以拿着暴力程序跑一个星期来跑出所需要的测试数据.一个星期跑不出来就延期一个星期机考好了,至于算法和讲题嘛,也就看看现场ac代码现学现卖咯?可能对你们来说很不幸的现实是,这道题似乎是个错题.给你一个初始n个元素的序列,有

数据结构——线段树

线段树是一种基于分治思想的类似于二叉树的数据结构,一般用于数组的信息统计,相比于树状数组,线段树有着更广阔的应用空间,但是相对的其代码量长,且常数大 一. 首先我们来讲线段树的建树过程,请看下图: 这张图就是线段树的存储结构,我们从最长的区间开始依次分成两部分,每一部分都有一个需要维护的权,建树过程比较简单,代码如下: inline void build(int l,int r,int rt) //l表示当前的左端点,r表示右端点,rt是当前区间的编号 { if(l == r) //当左右端点相

[数据结构-线段树] poj 2528

在一面墙上贴海报,贴的顺序给出了,求最后能被看到的海报数量. 纯粹的线段树模拟题. 但数据范围给了10^7,超内存了. 实际上这里用了一个小技巧,虽然墙的宽度是很大的,但海报数量只有10000,所以这10^7个数中真正用到的数很少,这样的话就只需要把没用到的数给"删去",剩下来的数从小到大映射为新的数,这样空间复杂度就大大降低了. 比如题目给的样例: 1 4 2 6 8 10 3 4 7 10   用到的数有:1 2 3 4 6 7 8 10 可以把它们映射为: 1 2 3 4 6 7

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树

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

这里是以区间最大值为例,要修改成其他的运算,注意修改每个函数的运算以及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