線段樹———區間最大數(線段樹入門)


線段樹初級(區間最大數)

其實就是對樹進行二分查找      (當然需要結合遞歸)

思路:

要從區間中找到最大數,當然可以暴力求解,但你不怕超時嗎???

so      讓我們來學習線段樹吧!!!!!!!!!!!!!!!

 

在c++里下面這個代碼是極快的(哇咔咔!!!)

 




 

 

題目描述

給出一列數共N個,將其從1到N編號,進行M次查詢[X, Y](X<=Y),給出第X個數到第Y個數間最大的數。

輸入

一組測試數據,第一行輸入N,M(1<=N, M<=10^5),第二行N個數;之后M行,每行分別為X,Y。給出一列數共N個,將其從1到N編號,進行M次查詢[X, Y](X<=Y),給出第X個數到第Y個數間最大的數。

輸出

對於每個[X, Y]輸出編號在X和Y之間(包括X,Y)的最大值。每行輸出一個結果。

樣例輸入

5 2
4 3 1 2 5
1 4
2 5

樣例輸出

4
5

 




 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 100010
 
struct N
{
     int l, r, max;
} tree[maxn * 4]; //注意乘三
 
int num[maxn];
 
void build( int node, int l, int r)
{
     tree[node].l = l;
     tree[node].r = r;
 
     if (l == r)
     {
         scanf ( "%d" , &tree[node].max);
         return ;
     }
 
     int mid = (l + r) / 2;
     build(node * 2, l, mid);
     build(node * 2 + 1, mid + 1, r);
     tree[node].max = max(tree[node << 1].max, tree[node << 1 | 1].max);
     return ;
}
 
int query( int node, int ql, int qr)
{
     int l = tree[node].l;
     int r = tree[node].r;
 
     if (l == ql && r == qr)
         return tree[node].max;
     //if (l == r) return tree[node].max;
     int mid = (l + r) / 2;
     if (qr <= mid)
         return query(node << 1, ql, qr);
     else if (ql > mid)
         return query(node << 1 | 1, ql, qr);
     else
         return max(query(node << 1, ql, mid), query(node << 1 | 1, mid + 1, qr));
}
 
int main()
{
     int n, m;
     int ql, qr;
     scanf ( "%d %d" , &n, &m);
     build(1, 1, n);
     for ( int i = 0; i < m; i++)
     {
         scanf ( "%d %d" , &ql, &qr);
         printf ( "%d\n" , query(1, ql, qr));
     }
}

 

用2*n和2*n+1不會出現遺漏和重復的樹編號,這樣就可以完美的遞歸啦!!!!!!!!!!!!!1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM