首页 > 代码库 > hihocoder 1077线段树

hihocoder 1077线段树

http://hihocoder.com/problemset/problem/1077

#include <bits/stdc++.h>using namespace std;#define ll long long#define co(x) cout << (x) << endl#define ci(x) cin >> (x)#define sd(x) scanf("%d",&x)#define sf(x) scanf("%lf",&x)#define pc(x) printf("%c",x)#define pd(x) printf("%d",x)#define gcd(x,y) __gcd(x,y)#define w(x) while(x)#define fo(i,j,k) for(int (i) = (j); (i) < (k); (i)++)#define en cout << endl;#define INF 2147483645#define Maxn 1000010struct Node{    int left,right;    int val;}A[Maxn<<2];void Build(int i,int left,int right){    A[i].left = left;    A[i].right = right;    if(left == right){//如果该结点是根节点就赋值        ci(A[i].val);        return ;    }    int mid = (left+right) >> 1;    Build( i<<1,left,mid );//向两边递归    Build(i<<1|1,mid+1,right );    A[i].val = min( A[i<<1].val,A[i<<1|1].val );    //取较小的值(其他类比)}void update(int i,int p,int val){    if( A[i].left == A[i].right ){//找到根结点        A[i].val = val;//修改        return ;    }    if( p <= A[i<<1].right ){//如果结点P在比A[i]的右儿子的右区间小(在右儿子的区间内)        update( i<<1,p,val );//向右儿子的左区间更新节点    }    if( p >= A[i<<1|1].left ){//如果比左儿子的左区间大,则向右更新节点        update(i<<1|1,p,val);    }//向两边同时递归更新节点的值,保证每个被影响的值都被更新    A[i].val = min( A[i<<1].val,A[i<<1|1].val );}// 如果该行描述一次商品的重量的更改,则接下来为两个整数Pi,Wi,// 表示位置编号为Pi的商品的重量变更为Wiint query(int i,int left,int right){ //left为查询的区间    if( A[i].left >= left && A[i].right <= right ){//在查询区间内,返回该节点的值??        return A[i].val;    }    int a = INF,b = INF;    if( left <= A[i<<1].right ){ //如果左范围在A[i]的右儿子的左边,就递归向左边查询        a = query(i << 1,left,right);    }    if( right >= A[i<<1|1].left ){//如果右范围在A[i]的左儿子的右边,就递归向右查询        b = query(i<<1|1,left,right);    }    return min(a,b);//回朔返回左右儿子的较小值}int main(){    int N,M,a,b,c;    while( sd(N)!=EOF ){        Build(1,1,N);        ci(M);        fo(i,0,M){            scanf("%d %d %d",&a,&b,&c);            if(a){                update(1,b,c);            }else{                printf("%d\n",query(1,b,c));            }        }    }}

 

hihocoder 1077线段树