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)); } } } }