线段树学习小记 Hdu 1754+Poj 3264 (区间最值)

来源:互联网 发布:starbound mac 编辑:程序博客网 时间:2024/06/05 03:29

很基础的数据结构,一些高级算法比如树链剖分什么的都要用到它来实现。

学习资料:

数据结构之线段树 | 董的博客
http://dongxicheng.org/structure/segment-tree/

NotOnlySuccess | 线段树专辑
http://www.notonlysuccess.com/index.php/segment-tree/


Hdu 1754

#include <cstdio>#define min(x,y) ((x)<(y)?(x):(y))#define max(x,y) ((x)>(y)?(x):(y))const int INF=0x7fffffff;const int NUM=200005*3;struct Node{int nmax,left,right;}a[NUM];int MAX;void Build (int t,int left,int right){a[t].left=left;a[t].right=right;a[t].nmax=-INF;if (left==right)return;int mid=(left+right)>>1;Build(t*2,left,mid);Build(t*2+1,mid+1,right);}void Insert (int t,int target,int val){if (a[t].left==target && a[t].right==target){a[t].nmax=val;return;}a[t].nmax=max(a[t].nmax,val);int mid=(a[t].left+a[t].right)>>1;if (target<=mid)Insert(t*2,target,val);elseInsert(t*2+1,target,val);}void Query (int t,int left,int right){if (a[t].left==left && a[t].right==right){MAX=max(MAX,a[t].nmax);return;}int mid=(a[t].left+a[t].right)>>1;if (right<=mid)Query(t*2,left,right);else if (left>mid)Query(t*2+1,left,right);else{Query(t*2,left,mid);Query(t*2+1,mid+1,right);}}int main (){#ifdef ONLINE_JUDGE#else    freopen("read.txt","r",stdin);#endifint N,M;while (~scanf("%d%d",&N,&M)){Build (1,1,N);int i,score;for (i=1;i<=N;i++){scanf("%d",&score);Insert(1,i,score);}int left,right;char str[5];for (i=1;i<=M;i++){scanf("%s%d%d",str,&left,&right);if (str[0]=='Q'){MAX=-INF;Query (1,left,right);printf ("%d\n",MAX);}else{Insert(1,left,right);}}}return 0;}


Poj 3264

给出n个数的数列,Q次查询,每次查询某个区间的最大最小值之差。

#include <cstdio>#define min(x,y) ((x)<(y)?(x):(y))#define max(x,y) ((x)>(y)?(x):(y))const int INF=0x7fffffff;const int NUM=200005;struct Node{int nmax,nmin,left,right;}a[NUM];int MAX,MIN;void Build (int t,int left,int right){a[t].left=left;a[t].right=right;a[t].nmin=INF;a[t].nmax=-INF;if (left==right)return;int mid=(left+right)>>1;Build(t*2,left,mid);Build(t*2+1,mid+1,right);}void Insert (int t,int target,int val){if (a[t].left==target && a[t].right==target){a[t].nmax=a[t].nmin=val;return;}a[t].nmax=max(a[t].nmax,val);a[t].nmin=min(a[t].nmin,val);int mid=(a[t].left+a[t].right)>>1;if (target<=mid)Insert(t*2,target,val);elseInsert(t*2+1,target,val);}void Query (int t,int left,int right){if (a[t].left==left && a[t].right==right){MIN=min(MIN,a[t].nmin);MAX=max(MAX,a[t].nmax);return;}int mid=(a[t].left+a[t].right)>>1;if (right<=mid)Query(t*2,left,right);else if (left>mid)Query(t*2+1,left,right);else{Query(t*2,left,mid);Query(t*2+1,mid+1,right);}}int main (){#ifdef ONLINE_JUDGE#else    freopen("read.txt","r",stdin);#endifint N,Q;while (~scanf("%d%d",&N,&Q)){Build (1,1,N);int i,high;for (i=1;i<=N;i++){scanf("%d",&high);Insert(1,i,high);}int left,right;for (i=1;i<=Q;i++){scanf("%d%d",&left,&right);if (left == right)     //左右值相等则区间内只有一个数,差值必为0printf("0\n");else{MAX=-INF;MIN=INF;Query (1,left,right);printf ("%d\n",MAX-MIN);}}}return 0;}