pku 暑假培训1 线段树和树状数组
2012-07-17 11:29
337 查看
今天是郭炜老师讲的线段树和树状数组,我还记得假期时雄哥讲的这个方面,讲的更加深入一些,举了几道例题让我们了解线段树的性质和应用(主要是开辟的结构体内应当存些什么内容),线段树的离散化,以及树状数组的证明问题。讲的例题貌似和雄哥讲的一样。
下面附上自己的代码和讲解:
poj 3264 line up
下面附上自己的代码和讲解:
poj 3264 line up
#include<stdio.h> const int MAX=-9999999; const int MIN= 9999999; struct node{ int left ,right; // 线段树上的区间长度 int nmax,nmin; //每个区间上的最大值和最小值 struct node *pleft,*pright; //左孩子指针,有孩子指针 要注意到,完全二叉树的叶子结点数为n,则总结点的个数为2n-1; } tree[500000]; int count=0; int pmax,pmin; int min(int a,int b){ //比较大小函数 if(a<b)return a; else return b; } int max(int a,int b){ if(a>b)return a; else return b; } void buildtree(struct node *proot,int l,int r) //建树的函数 { proot->left=l; //确定区间的范围 proot->right=r; proot->nmax=MAX; //初始化最大值,最小值 proot->nmin=MIN; if(l!=r){ count++; proot->pleft=tree+count; // 用数组的首地址来表示树 buildtree(proot->pleft,l,(r+l)/2); count++; proot->pright=tree+count; buildtree(proot->pright,(r+l)/2+1,r); //递归的建树 } } void insert(struct node *proot,int num,int i) //插入数据,并对数据进行更新 { if(proot->left==i&&proot->right==i){ // 遇到叶子结点的更新 proot->nmax=num; proot->nmin=num; return ; } proot->nmax=max(proot->nmax,num); proot->nmin=min(proot->nmin,num); // 遇到包含节点的区间的更新 if(i<=(proot->left+proot->right)/2){ insert(proot->pleft,num,i); } if(i>=(proot->left+proot->right)/2+1){ insert(proot->pright,num,i); } } void query(struct node *proot,int b,int e) { if(pmax>=proot->nmax && pmin<=proot->nmin)return; // 一种剪枝的方法 if(proot->left==b&&proot->right==e) { pmax=max(proot->nmax,pmax); //寻找最大值,最小值 pmin=min(proot->nmin,pmin); return; } if(e<=(proot->left+proot->right)/2)query(proot->pleft,b,e); //继续进行遍历 else {if(b>=(proot->left+proot->right)/2+1)query(proot->pright,b,e); else { query(proot->pleft,b,(proot->left+proot->right)/2); query(proot->pright,(proot->left+proot->right)/2+1,e); } } } int main() { int n,q,i,num,s,e; scanf("%d %d",&n,&q); buildtree(tree,1,n); for(i=1;i<=n;i++) { scanf("%d",&num); insert(tree,num,i); } for(i=1;i<=q;i++) { scanf("%d %d",&s,&e); pmax=MAX; // 全局变量记录最大值和最小值 pmin=MIN; query(tree,s,e); printf("%d\n",pmax-pmin); } }
相关文章推荐
- [Pku 2352 2155 Hdu 3584] 线段树(五) {树状数组}
- [PKU暑课笔记] 趁机膜一发线段树和树状数组
- pku2886 Who Gets the Most Candies?(线段树+反素数打表)
- POJ 3321 Apple Tree (线段树 & 树状数组)
- poj3468 A Simple Problem with Integers(用线段树和树状数组实现)
- 比较快也比较漂亮的熟练剖分模板(BZOJ 1036:树剖+线段树 BZOJ 1103:树剖+树状数组)
- PKU 3468 线段树
- 【线段树】PKU2777 区间更新区间询问(位优化)
- poj 2761 Feed the dogs 平衡树,线段树,树状数组
- 线段树练习五(+树状数组)
- PKU 3667 Hotel (线段树,区间合并,最长连续区间)
- HDU~1556 Color the ball(线段树区间更新||树状数组)
- CodeForces - 668D Little Artem and Time Machine(线段树||树状数组)
- SPOJ 227 Ordering the Soldiers 线段树 / 树状数组
- 树状数组和线段树
- BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理
- 【uva12345】dynamic len 树状数组套线段树
- poj2352~树状数组~线段树尝试失败~
- hdu 1166(线段树或者树状数组)
- PKU 3368(线段树 + 离散化)