線段樹單點替換區間最值 及思想
阿新 • • 發佈:2018-11-12
線段樹詳細講解:https://www.cnblogs.com/TheRoadToTheGold/p/6254255.html
上面的部落格講解的線段樹(包括區間修改)非常好,模板寫的也很好。
<span style="font-size:18px;">//HDU1754 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=200000+100; int maxv[MAXN*4]; #define lson i*2,l,m #define rson i*2+1,m+1,r void PushUp(int i) { maxv[i] = max(maxv[i*2] , maxv[i*2+1]); } void build(int i,int l,int r) { if(l==r) { scanf("%d",&maxv[i]); return ; } int m=(r+l)/2; build(lson); build(rson); PushUp(i); } int query(int ql,int qr,int i,int l,int r) { if(ql<=l&&r<=qr) return maxv[i]; //返回的該值為一個候選答案。直到把所有節點包含的區間都在要查詢區間,的節點值都比較了一遍。 int m=(l+r)/2; int max_v=-1e8; if(ql<=m)max_v=max(max_v,query(ql,qr,lson)); if(qr>m)max_v=max(max_v,query(ql,qr,rson)); return max_v; } void update(int q,int v,int i,int l,int r) //將a[q]換成v。i表示節點,l,r表示左右區間,更新的時候從(1,n)開始。思想就是先找到q的葉節點,往上依次更新。 { if(l==r) { maxv[i]=v; return ; } int m=(r+l)/2; if(q<=m)update(q,v,lson); else update(q,v,rson); PushUp(i); } int main() { int n,m; while(scanf("%d%d",&n,&m)==2&&n&&m) { build(1,1,n); while(m--) { char str[10]; int x,y; scanf("%s%d%d",str,&x,&y); if(str[0]=='Q')printf("%d\n",query(x,y,1,1,n)); else update(x,y,1,1,n); } } return 0; } </span>