- //線段樹中不是懶方法創建,修改(某個數據),查詢區間和(sum)與最大值(max)
- #include<cstdio>
- #include<iostream>
- using namespace std;
- const int MAXN=1000;
- struct
- {
- int left,right; //區間的端點
- int max,sum; //視題目要求而定
- } tree[MAXN*4] ;
- int a[MAXN]={0,1,2,3,4,5,6,7,8,9,10} ;//僅用於實驗
- int max(int a,int b)
- {
- return a>b?a:b;
- }
- void build(int id,int l,int r)
- {
- tree[id].left=l; tree[id].right=r;
- if (l==r)//已到達葉子
- {
- tree[id].sum=tree[id].max=a[l];//在根結點上,sum,max 的結果相等,都爲a[l]自己
- //tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
- // tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
- return;
- }
- else
- {
- int mid=(l+r)/2;
- build(id*2,l,mid);
- build(id*2+1,mid+1,r);
- tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
- tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
- }
- }
- void update(int id,int pos,int val)//此外爲將第pos個數改成val
- {
- if (tree[id].left==tree[id].right)
- {
- tree[id].sum=tree[id].max=val;
- }
- else
- {
- int mid=(tree[id].left+tree[id].right)/2;
- if (pos<=mid) update(id*2,pos,val);//更新左子樹
- else update(id*2+1,pos,val);//更新右子樹
- tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
- tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
- }
- }
- int query(int id,int l,int r) //這是查詢總和的函數
- {
- if (tree[id].left==l&&tree[id].right==r)
- return tree[id].sum; //詢問總和
- else
- {
- int mid=(tree[id].left+tree[id].right)/2;
- if (r<=mid) return query(id*2,l,r);
- else if (l>mid)
- return query(id*2+1,l,r);
- else
- return query(id*2,l,mid)+query(id*2+1,mid+1,r);
- }
- }
- int query_max(int id,int l,int r)
- {
- if(tree[id].left==l&&tree[id].right==r)
- {
- return tree[id].max;
- }
- else
- {
- int mid=(tree[id].left+tree[id].right)/2;
- if(r<=mid) return query_max(id*2,l,r);
- else if(l>mid) return query_max(id*2+1,l,r);
- else return query_max(id*2,l,mid)+query_max(id*2+1,mid+1,r);
- }
- }
- int main()
- {
- int n=10;
- build(1,1,n);
- // printf("%d\n",query(1,1,10));
- cout<<query_max(1,1,10)<<endl;
- update(1,3,15);
- cout<<query_max(1,1,10)<<endl;
- }