hihocoder 1077线段树

时间:2021-10-29 09:12:53

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 1000010

struct Node{
    int left,right;
    int val;
}A[Maxn<<];

void Build(int i,int left,int right){
    A[i].left = left;
    A[i].right = right;
    if(left == right){//如果该结点是根节点就赋值
        ci(A[i].val);
        return ;
    }
    ;
    Build( i<<,left,mid );//向两边递归
    Build(i<<|,mid+,right );
    A[i].val = min( A[i<<].val,A[i<<|].val );
    //取较小的值(其他类比)
}

void update(int i,int p,int val){
    if( A[i].left == A[i].right ){//找到根结点
        A[i].val = val;//修改
        return ;
    }
    ].right ){//如果结点P在比A[i]的右儿子的右区间小(在右儿子的区间内)
        update( i<<,p,val );//向右儿子的左区间更新节点
    }
    |].left ){//如果比左儿子的左区间大,则向右更新节点
        update(i<<|,p,val);
    }//向两边同时递归更新节点的值,保证每个被影响的值都被更新
    A[i].val = min( A[i<<].val,A[i<<|].val );
}
// 如果该行描述一次商品的重量的更改,则接下来为两个整数Pi,Wi,
// 表示位置编号为Pi的商品的重量变更为Wi

int 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;
    ].right ){ //如果左范围在A[i]的右儿子的左边,就递归向左边查询
        a = query(i << ,left,right);
    }
    |].left ){//如果右范围在A[i]的左儿子的右边,就递归向右查询
        b = query(i<<|,left,right);
    }
    return min(a,b);//回朔返回左右儿子的较小值
}

int main(){
    int N,M,a,b,c;
    while( sd(N)!=EOF ){
        Build(,,N);
        ci(M);
        fo(i,,M){
            scanf("%d %d %d",&a,&b,&c);
            if(a){
                update(,b,c);
            }else{
                printf(,b,c));
            }
        }
    }
}