線段樹 功能:update:單點替換 query:區間最值 hdu1754
阿新 • • 發佈:2018-11-09
hud 1754 http://acm.hdu.edu.cn/showproblem.php?pid=1754
(0)定義
(2)單點替換
(3) 區間最大值
線段樹,不會的話可以多畫畫自己理解理解;
附上全部程式碼
(0)定義
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn =222222;
int MAX[maxn<<2]; // maxn *4;
(1) 建立線段樹
void PushUp(int rt) // rt :當前節點的編號
{ //更新該節點的資料 ,這裡是求該節點的最大值 MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); // <<1==*2 ,<<1|1==*2+1; } void build(int l,int r,int rt)//建樹 ,[l.r]當前節點的區間,rt :當前的節點 { if(r==l){ //到達子葉節點, scanf("%d",&MAX[rt]); return ; } int m=(l+r)>>1; // 除以2//左右遞迴 build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(rt); //更新資訊 }
(2)單點替換
void update(int p,int sc,int l,int r,int rt){ // P:替換第幾個,sc:更換的資料 在[l.r]中查詢 if(l==r){ MAX[rt]=sc; return ; } int m=(l+r)>>1; //判斷 p 左還是右 if(p<=m){ update(p,sc,l,m,rt<<1); }else{ update(p,sc,m+1,r,rt<<1|1); } PushUp(rt);// 子葉替換後 當前節點更新 }
(3) 區間最大值
int query(int L,int R,int l,int r,int rt){ //[L,R] 所求區間 [l,r]當前區間 if(L<=l&&r<=R){ return MAX[rt]; } int m=(l+r)>>1; int ret=0; if(L<=m)ret=max(ret,query(L,R,l,m,rt<<1)); if(m<R)ret=max(ret,query(L,R,m+1,r,rt<<1|1)); return ret; }
線段樹,不會的話可以多畫畫自己理解理解;
附上全部程式碼
#include<iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn =222222; int MAX[maxn<<2]; // maxn *4; void PushUp(int rt) // rt :當前節點的編號 { //更新該節點的資料 ,這裡是求該節點的最大值 MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); // <<1==*2 ,<<1|1==*2+1; } void build(int l,int r,int rt)//建樹 ,[l.r]當前節點的區間,rt :當前的節點 { if(r==l){ //到達子葉節點, scanf("%d",&MAX[rt]); return ; } int m=(l+r)>>1; // 除以2 //左右遞迴 build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(rt); //更新資訊 } //單點替換 void update(int p,int sc,int l,int r,int rt){ // P:替換第幾個,sc:更換的資料 在[l.r]中查詢 if(l==r){ MAX[rt]=sc; return ; } int m=(l+r)>>1; //判斷 p 左還是右 if(p<=m){ update(p,sc,l,m,rt<<1); }else{ update(p,sc,m+1,r,rt<<1|1); } PushUp(rt);// 子葉替換後 當前節點更新 } //區間最大值 int query(int L,int R,int l,int r,int rt){ //[L,R] 所求區間 [l,r]當前區間 if(L<=l&&r<=R){ return MAX[rt]; } int m=(l+r)>>1; int ret=0; if(L<=m)ret=max(ret,query(L,R,l,m,rt<<1)); if(m<R)ret=max(ret,query(L,R,m+1,r,rt<<1|1)); return ret; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ build(1,n,1);// 建樹 從 1 到 n ,當前節點為1 while(m--){ char op[2]; int a,b; scanf("%s%d%d",op,&a,&b); if(op[0]=='Q'){ int k=query(a,b,1,n,1); printf("%d\n",k); //cout<<k<<endl; } else update(a,b,1,n,1); } } return 0; }