hihoCode r#1077 : RMQ问题再临-线段树

思路:全都已经介绍了。连步骤它都告诉你了。差的只是实现了。两种实现方法:(1)用链表做树(2)用顺序表做树。顺序表的速度更快,因为不用管链的问题。空间谁更省?树是接近平衡的,也就是叶子节点在最下两层,但是如果树深一点,用顺序表就会浪费很多空间,这底层可能比之前存的都要多,但是链表却每个点都要消耗。总的来讲,顺序表更省,即使浪费了一半,也只是一半乘以4个字节,可是链表就每个节点必须浪费8字节了。但是链表却能应对更多情况。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n, q, L, R, op, P, W;
 4
 5 struct node
 6 {
 7     int v;
 8     node *ll,*rr;
 9 };
10
11 node* create()  //创建节点
12 {
13     node *tmp=new(node);
14     tmp->v=-1;
15     tmp->ll=tmp->rr=0;
16     return tmp;
17 }
18
19 node* init_tree(int l,int r)    //初始化树
20 {
21     node *tmp=create();
22     if(l==r)
23     {
24         scanf("%d",&tmp->v);
25         return tmp;
26     }
27     tmp->ll=init_tree(l,(r+l)/2);
28     tmp->rr=init_tree((r+l)/2+1,r);
29     tmp->v= tmp->ll->v < tmp->rr->v?tmp->ll->v:tmp->rr->v;
30     return tmp;
31 }
32
33 int query(int l,int r,int LL,int RR,node *t)    //查询(欲查询的左,右,区间下限,上限,根)
34 {
35     if(l==LL&&r==RR)    return  t->v;
36     int mid=((LL+RR)>>1);
37     if(l>mid)     return query(l, r, mid+1, RR, t->rr);
38     if(r<=mid)    return query(l, r, LL, mid, t->ll);
39     return min( query(l,mid,LL,mid,t->ll),query(mid+1,r,mid+1,RR,t->rr) );
40 }
41
42 void update(int LL,int RR,node *t)   //修改,深搜,搜到后一直往回改。
43 {
44     if(LL==RR)
45     {
46         t->v=W;
47         return ;
48     }
49     int mid=((LL+RR)>>1);
50     int tmp;
51     if(P>mid)    update(mid+1,RR,t->rr);  //要改的在右边
52     else    update(LL,mid,t->ll);
53     t->v=min(t->ll->v,t->rr->v);
54 }
55
56 int main()
57 {
58     freopen("input.txt", "r", stdin);
59     cin>>n;
60     node *tree=init_tree(1,n);
61     cin>>q;
62     for(int i=0; i<q; i++)
63     {
64         scanf("%d",&op);
65         if(op)  //修改
66         {
67             scanf("%d%d",&P,&W);
68             update(1,n,tree);
69         }
70         else    //查询
71         {
72             scanf("%d%d",&L,&R);
73             printf("%d\n",query(L,R,1,n,tree) );
74         }
75     }
76     return 0;
77 }

AC代码(链实现)

时间: 2024-08-24 12:28:07

hihoCode r#1077 : RMQ问题再临-线段树的相关文章

hihoCoder #1077 RMQ问题再临-线段树

#1077 : RMQ问题再临-线段树 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并且依次标号为1到N,每次小Hi都给出一段区间[L, R],小Ho要做的是选出标号在这个区间内的所有商品重量最轻的一种,并且告诉小Hi这个商品的重量.但是在这个过程中,可能会因为其他人的各种行为,对某些位置上的商品的重量产生改变(如更换了其他种类的商品

Hihocoder #1077 : RMQ问题再临-线段树(线段树:结构体建树+更新叶子往上+查询+巧妙使用father[]+线段树数组要开大4倍 *【模板】)

#1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并且依次标号为1到N,每次小Hi都给出一段区间[L, R],小Ho要做的是选出标号在这个区间内的所有商品重量最轻的一种,并且告诉小Hi这个商品的重量.但是在这个过程中,可能会因为其他人的各种行为,对 某些位置上的商品的重量产生改变(如更换了其他种类的商品). 小Ho提出了两种非常简单的方法,但是都不能

线段树水题 #1077 : RMQ问题再临-线段树

#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; #define maxn 1000000 + 10 #define Lson L, mid, root<<1 #define Rson mid+1, R, root<<1|1 #define

hihoCoder week19 RMQ问题再临-线段树 单点更新 区间查询

单点更新 区间查询 #include <bits/stdc++.h> using namespace std; #define m ((l+r)/2) #define ls (rt<<1) #define rs (rt<<1|1) const int N = 2e6+10; int s[N], tr[N]; void build(int rt,int l,int r) { if(l == r) { tr[rt] = s[l]; return ; } build(ls,

CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://codeforces.com/problemset/problem/52/C You are given circular array a0,?a1,?...,?an?-?1. There are two types of operations with it: inc(lf,?rg,?v) - this operation increases each element on the segm

Uva 12299 RMQ with Shifts(线段树 + 单点更新 )

Uva 12299 RMQ with Shifts (线段树 + 单点更新) 题意: 对于给定的序列 x[i]给出一个操作 shift(a,b,c,d,e) 对应的是将 x[a]与x[b] x[b]与x[c] 这样相邻的两两交换For example, if A={6, 2, 4, 8, 5, 1, 4}then shift(2, 4, 5, 7) yields {6, 8, 4, 5, 4, 1, 2}. After that,shift(1, 2) yields {8, 6, 4, 5, 4

湖南省第七届大学生计算机程序设计竞赛 RMQ with Shifts (线段树)

RMQ with Shifts 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=R), we report the minimum value among A[L], A[L+1], -, A[R]. Note that the indic

UVA12299 - RMQ with Shifts(线段树)

题目链接 题目大意:要求你查询某一段的最小值,但是还有一个shift操作,将(a0, a1, a2, a3..ak)这个K个位置的数字互相对掉,例如a0位置的值变成a1,a1位置的值变成a2...ak位置的值变成a0. 解题思路:因为shift后面的操作数最多30个,所以可以用线段树单点修改.复杂度n*logn.用sscanf函数挺耗时的,还是自己写处理函数. 代码: #include <cstdio> #include <cstring> #include <algorit

nyoj 568——RMQ with Shifts——————【线段树单点更新、区间求最值】

RMQ with Shifts 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=R), we report the minimum value among A[L], A[L+1], …, A[R]. Note that the indic