线段树(自敲:建树,查找最大值,更新结点值)

HDU1754

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 const int MaxSIZE = 2e6 + 10;
  6
  7 typedef struct {
  8     int Max ;
  9     int left, right ;
 10 } NODE ;
 11
 12 int     n, m ;
 13 int     num [MaxSIZE] ;
 14 NODE    tree[MaxSIZE * 20] ;
 15
 16
 17 int build (int root, int left, int right) {
 18     int mid ;
 19
 20     tree[root].left     = left ;
 21     tree[root].right    = right ;
 22
 23     if (left == right) {
 24         return tree[root].Max = num[left] ;
 25     }
 26     mid = (left + right) / 2 ;
 27
 28
 29     int a, b ;
 30     a = build (2 * root, left, mid) ;
 31     b = build (2 * root + 1, mid + 1, right) ;
 32
 33     return tree[root].Max = max (a, b) ;
 34 }
 35
 36 int Find (int root, int left, int right) {
 37     int mid ;
 38
 39     if (tree[root].left > right || tree[root].right < left)
 40         return 0 ;
 41
 42     if (left <= tree[root].left && tree[root].right <= right)
 43         return tree[root].Max ;
 44
 45     int a, b ;
 46     a = Find (2 * root, left, right) ;
 47     b = Find (2 * root + 1, left, right) ;
 48
 49     return max (a, b) ;
 50 }
 51
 52
 53 int update (int root, int pos, int val) {
 54
 55     if (pos < tree[root].left || tree[root].right < pos)
 56         return tree[root].Max ;
 57
 58     if (tree[root].left == pos && tree[root].right == pos)
 59         return tree[root].Max = val ;
 60
 61     int a, b ;
 62     a = update (2 * root, pos, val) ;
 63     b = update (2 * root + 1, pos, val) ;
 64
 65     tree[root].Max = max (a, b) ;
 66
 67     return tree[root].Max ;
 68 }
 69
 70
 71 int main() {
 72     int n, ask_n;
 73     while (~scanf("%d%d", &n, &ask_n)) {
 74     //while (cin >> n >> ask_n) {
 75         memset(num, 0, sizeof(num));
 76
 77         for (int i = 1; i <= n; ++ i) {
 78             //cin >> num[i];
 79             scanf("%d", &num[i]);
 80         }
 81
 82         build (1, 1, n);
 83
 84         char op; int x, y;
 85
 86         for (int j = 0; j < ask_n; ++ j) {
 87             getchar();
 88             scanf("%c%d%d", &op, &x, &y);
 89             //cin >> op >> x >> y;
 90             if (op == ‘Q‘) {
 91                 int ans = Find (1, x, y);
 92                 cout << ans << endl;
 93             } else if (op == ‘U‘) {
 94                 num[x] = y;
 95                 update (1, x, y);
 96             }
 97         }
 98     }
 99     return 0;
100 }

线段树(自敲:建树,查找最大值,更新结点值)

时间: 2024-10-12 05:39:38

线段树(自敲:建树,查找最大值,更新结点值)的相关文章

POJ 2528 Mayor&#39;s posters(线段树区间染色+离散化或倒序更新)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59239   Accepted: 17157 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

Just a Hook(线段树之点的成段更新)

萌萌哒的传送门 /* * hdu 1698 * 线段树的点的成段更新 * 这道题不用预先建树,只需把1号节点延迟标记下就行 */ #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <queue> #include <vector> #include <cstdlib>

Mayor&#39;s posters(线段树之点的成段更新加离散化)

bin神的萌萌哒专题 这道题目也是简单区间更新的线段树题目,不过题目的数据范围很大,直接搞,时间空间的花费都会异常的高,所以就要用到离散化来优化时间空间复杂度. 何为离散化?........................ 简单地说就是对于给出的庞大数据进行一种数据上的缩小. 比如给你一段(1,10000)的区间,由于我们要的不是其区间长度,我们只需要知道这段区间的状态 如何,于是我们可以忽视其长度,把其表示成(1,2)这个区间长度极小的区间,这相当于物理上的质点. 当我们处理的问题上与其区间长

HDU 1754线段树基本操作,建树,更新,查询

代码线段树入门整理中有介绍. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 const int MAXNODE=1<<19; 7 const int MAX=1000003; 8 struct NODE{ 9 int left,right; 10 int value; 11 }node[

基本线段树模板(建树、点/区间修改、查询)

线段树主要用于区间记录信息(如区间和.最大最小值等),首先是建树: 这里以求和为例: 1 const int MAXM=50000; //定义 MAXM 为线段最大长度 2 3 int a[MAXM+5],segtree[(MAXM<<2)+5]; // a 数组为 main 函数中读入的内容,segtree 数组为需要查询的数的信息(如和.最值等),树的空间大小为线段最大长度的四倍 4 5 void build(int o,int l,int r){ //传入的参数为 o:当前需要建立的结点

UESTC 1073 秋实大哥与线段树(线段树---省时的建树)

题目链接:http://acm.uestc.edu.cn/#/problem/show/1073 “学习本无底,前进莫徬徨.” 秋实大哥对一旁玩手机的学弟说道. 秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构. 为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作. 秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值:一种是询问一段区间的和. Input 第一行包含一个整数n ,表示序列的长度. 接下来一行包含n  个整数a i  ,表示序列

hdu-1754 I Hate It【线段树】(求区间最大值)

题目链接:https://vjudge.net/contest/182746#problem/A I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                                    Total Submission(s): 96252    Accepted Submission(s): 36

kb-07线段树--10--dfs序建树

1 /* 2 hdu3974 3 dfs序建树,然后区间修改查询: 4 */ 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 #define MAX_N 50005 10 using namespace std; 11 12 int N,M; 13 struct Node 14 { 15 int to,next; 16 }edge[MAX_

poj 4047 Garden 线段树lazy标记与成段更新

题意: 给长度为n的序列及k(0<k<=n<=200000),m个操作p,x,y.其中(1)p==0:将x位置处的数变为y;(2)p==1:将x,y位置处的数互换.(3)p==2查询x-y位置之间连续k个数的和的最大值. 分析: 求连续区间的和最大,可以把区间看成一个点,这样这n-k+1个区间的最大和可以看做n-k+1个点的最大值,当更新原序列中位置x的值就相当于更新区间中x-k+1到x区间的值,然后用线段树做成段更新.成段更新要用到lazy标记,我的理解是:当更新或query的时候如果