用一维数组存储二叉树,利用二分查找降低效率
1.线段树的构造,区间查询
描述: 给定n(1<=n<=50000)个数,求任意区间中最大值最小值的差, eg: 输入: 6 3 1 7 3 4 2 5 1 5 4 6 2 2 输出: 6 3 0
//balanced lineup #include<iostream> #include<cstring> #include<climits> using namespace std; const int maxn=50001; const int inf=INT_MAX; #define max(a,b) a>b?a:b #define min(a,b) a<b?a:b #define L(a) ((a)<<1) //左孩子 #define R(a) (((a)<<1)+1) //右孩子 typedef struct node_t{ int left,right; int max,min; //区间里的最大值最小值 }node_t; int A[maxn];//用作输入数据 0位置未用 /*完全二叉树 结点从1开始 层次从1开始 用一维数组存储二叉树,空间约为4*n */ node_t node[4*maxn]; //数组存放结构体 int minx,maxx; //存放结果 void init(){ memset(node,0,sizeof(node)); } /*以t为结点,为区间A【l,r】建立线段树*/ void build(int t,int l,int r){ //懂了 node[t].left=l; node[t].right=r; if(l==r) { node[t].max=node[t].min=A[l]; return ; } const int mid=(l+r)/2; build(L(t),l,mid); build(R(t),mid+1,r); node[t].max=max(node[L(t)].max,node[R(t)].max); node[t].min=min(node[L(t)].min,node[R(t)].min); } //查询根结点为t,区间A[l,r] 的最大值最小值 void query(int t,int l,int r){ if(node[t].left==l&&node[t].right==r){ if(maxx<node[t].max) maxx=node[t].max; if(minx>node[t].min) minx=node[t].min; return ;} const int mid=(node[t].left+node[t].right)/2; if(l>mid){ query(R(t),l,r); }else if(r<=mid){ query(L(t),l,r);// }else { query(L(t),l,mid); query(R(t),mid+1,r); } } int main(){ int n,q,i; int a,b; cin>>n; for(int i=1;i<=n;i++) cin>>A[i]; init(); // cout<<"hello"<<endl; build(1,1,n); // cout<<"hello"<<endl; while(cin>>a>>b){ // cin>>a>>b; maxx=0; minx=inf; // cout<<"hello"<<endl; query(1,a,b); //A[a,b]之间的最大最小值 // cout<<"helo"<<endl; cout<<maxx<<" "<<minx<<endl; } return 0; }
2.单点更新,区间求和 未完待续