线段树,最大值查询位子(个人模版)

线段树,最大值查询位子:

  1 #include<cstdio>
  2 #include<climits>
  3 #include<algorithm>
  4
  5 using namespace std;
  6
  7 #define lson l, m, rt<<1
  8 #define rson m+1, r, (rt<<1)|1
  9
 10 int tree[111111<<2];
 11 int posn[111111<<2];
 12 void pushup(int rt)
 13 {
 14     if (tree[rt<<1] > tree[rt<<1|1])
 15     {
 16         tree[rt] = tree[rt<<1];
 17         posn[rt] = posn[rt<<1];
 18     }
 19     else
 20     {
 21         tree[rt] = tree[rt<<1|1];
 22         posn[rt] = posn[rt<<1|1];
 23     }
 24 }
 25 void build(int l, int r, int rt)
 26 {
 27     if (l == r)
 28     {
 29         scanf("%d", &tree[rt]);
 30         posn[rt] = l;
 31     }
 32     else
 33     {
 34         int m = (l + r) >> 1;
 35         build(lson);
 36         build(rson);
 37         pushup(rt);
 38     }
 39 }
 40 void update(int p, int val, int l, int r, int rt)
 41 {
 42     if (l == r)
 43     {
 44         tree[rt] = val;
 45     }
 46     else
 47     {
 48         int m = (l + r) >> 1;
 49         if (p <= m)
 50         {
 51             update(p, val, lson);
 52         }
 53         else
 54         {
 55             update(p, val, rson);
 56         }
 57         pushup(rt);
 58     }
 59 }
 60 int query(int L, int R, int l, int r, int rt, int *pos)
 61 {
 62     if (L <= l && r <= R)
 63     {
 64         *pos = posn[rt];
 65         return tree[rt];
 66     }
 67     else
 68     {
 69         int m = (l + r) >> 1;
 70         int ret1 = INT_MIN;
 71         int ret2 = INT_MIN;
 72         int pa, pb;
 73         int *pos1 = &pa;
 74         int *pos2 = &pb;
 75         if (L <= m)
 76         {
 77             ret1 = query(L, R,  lson, pos1);
 78         }
 79         if (R > m)
 80         {
 81             ret2 = query(L, R, rson, pos2);
 82         }
 83         if (ret1 > ret2)
 84         {
 85             *pos = pa;
 86         }
 87         else
 88         {
 89             *pos = pb;
 90             ret1 = ret2;
 91         }
 92         return ret1;
 93     }
 94 }
 95 int main(void)
 96 {
 97     int n, m;
 98
 99     while (scanf("%d", &n) != EOF)
100     {
101         build(1, n, 1);
102
103         scanf("%d", &m);
104         char op[2];
105         int a, b;
106         while (m--)
107         {
108             scanf("%s", op);
109             if (op[0] == ‘Q‘)
110             {
111                 int pos;
112                 printf("%d %d\n", pos, query(1, n, 1, n, 1, &pos));
113             }
114             else
115             {
116                 scanf("%d%d", &a, &b);
117                 update(a, b, 1, n, 1);
118             }
119         }
120         printf("\n");
121     }
122
123     return 0;
124 }
时间: 2024-11-10 07:08:37

线段树,最大值查询位子(个人模版)的相关文章

HDU 4638 Group (莫队算法||线段树离散查询)

题目地址:HDU 4638 先写了一发莫队,莫队可以水过.很简单的莫队,不多说. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <s

hdu1574 I Hate It (线段树,查询区间最大值)

Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目. 学生ID编号分别从1编到N. 第二行包含N个整数,

HDU 1754 I Hate it (线段树最大值模板)

思路:与我发表的上一遍求和的思想一样   仅仅是如今变成求最大值而已 AC代码: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; inline int Max(int a, int b) { return a > b ? a : b; } const int MAXN

HDU 4630 No Pain No Game (线段树离线查询)

题目地址:HDU 4630 这题一看数据范围,于是一直在思考n*logn的算法..实在没想到好方法,找了找题解,发现都是用的n*sqrt(n)*logn的方法...算了算,这个复杂度的确可以过..好吧.. 然后就可以先离线下来将询问按r值排序,然后枚举每个数,并且用sqrt(n)的方法枚举所有的约数,然后对于每个约数,对最近的一次出现的这个约数的地方进行更新.因为对于当前区间来讲,只要最近的这个地方更新了,那么前面的查询肯定都能查到这个地方的最大值,所以前面的不用更新. 代码如下: #inclu

【HDU-4614】Vases and Flowers(线段树双查询)

11946317 2014-10-23 09:08:28 Accepted 4614 437MS 2348K rid=11946317" target="_blank" style="color:rgb(26,92,200); text-decoration:none">3340 B G++ KinderRiven #include<cstdio> #include<cstring> #include<iostream&

hdu 5381 The sum of gcd(线段树等差数列区间修改+单点查询)

题意: 给出一个数组a,叫你每次询问如下等式的值. f(l,r)=∑ri=l∑rj=igcd(ai,ai+1....aj) 解析: 思考了很久终于理解了学长的思路 给你一个序列,这个序列的子序列gcd的个数不会超过logN个(N为每个数字,最大能取到的范围) 因为求gcd是递减的,每次至少除以2,所以gcd的个数只会有logN个. 然后让我们来看看题目要求的是什么. 所有子区间的gcd的和. 比如[1, 5]这个区间可以分解成如下子区间. [1, 1] [1, 2] [1, 3] [1, 4]

10.25算法训练——裸线段树

题目大意:对N(1<=N<=50000)个数进行连续进行M(1<=M<=200000)次询问:问1-N之间任意连续区间最大值和最小值之差. 之前学过线段树,学的是模版题,求解的问题是在一段区间内任意加减,然后再询问任意一段之区间的和. 这次的问题和之前学的模版题相同之处是:查询的是一段连续区间的信息. 不同之处在于:区间求和问题需要在线段树的每个结点记录其左儿子和右儿子所有结点之和.也就是说每个结点的信息是一个数. 所以之后的查询操作,也是不断去访问线段树的结点,将这些结点上的数加

COGS 2554. [福利]可持久化线段树

2554. [福利]可持久化线段树 ★★☆   输入文件:longterm_segtree.in   输出文件:longterm_segtree.out   简单对比时间限制:3 s   内存限制:256 MB [题目描述] 为什么说本题是福利呢?因为这是一道非常直白的可持久化线段树的练习题,目的并不是虐人,而是指导你入门可持久化数据结构. 线段树有个非常经典的应用是处理RMQ问题,即区间最大/最小值询问问题.现在我们把这个问题可持久化一下: Q k l r 查询数列在第k个版本时,区间[l,

AC日记——[福利]可持久化线段树 cogs 2554

2554. [福利]可持久化线段树 ★★☆   输入文件:longterm_segtree.in   输出文件:longterm_segtree.out   简单对比时间限制:3 s   内存限制:256 MB [题目描述] 为什么说本题是福利呢?因为这是一道非常直白的可持久化线段树的练习题,目的并不是虐人,而是指导你入门可持久化数据结构. 线段树有个非常经典的应用是处理RMQ问题,即区间最大/最小值询问问题.现在我们把这个问题可持久化一下: Q k l r 查询数列在第k个版本时,区间[l,