您的位置:首页 > 其它

HNCU专题训练_线段树(2)

2013-08-04 16:15 295 查看
1.统计颜色,或运算的运用
2.区间第k大数
3.一个很经典的题
5.求区间相等数字的个数
6.RMQ模板题,区间最大值和最小值的差

1.很好的思路,用或运算来避免左右儿子树总相同颜色的情况。由于
T颜色种类最多30种,__int64 足够用了。
注意初始化就行。

5.关键是写对make_up()这个函数,向上更新需要考虑的问题。经典题型。

1001

/*
求区间[l,r],最大值和最小值的差值。
*/

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAX 1000010
using namespace std;

struct node
{
int l;
int r;
int min;
int max;
}f[50003*4];
int Date[50003];

int hmax(int x,int y)
{
return x>y? x:y;
}

int hmin(int x,int y)
{
return x>y? y:x;
}

void build(int l,int r,int n)
{
int mid=(l+r)/2;
f
.l=l;
f
.r=r;
if(l==r)
{
f
.max=Date[l];
f
.min=Date[l];
return;
}
build(l,mid,n*2);
build(mid+1,r,n*2+1);
f
.max=hmax(f[n*2].max,f[n*2+1].max);
f
.min=hmin(f[n*2].min,f[n*2+1].min);
}

void query(int l,int r,int *a,int *b,int n)
{
int mid=(f
.l+f
.r)/2;
if(f
.l==l && f
.r==r)
{
if(f
.min<*a)
*a=f
.min;
if(f
.max>*b)
*b=f
.max;
return;
}
if(mid>=r)
query(l,r,a,b,n*2);
else if(mid<l)
query(l,r,a,b,n*2+1);
else
{
query(l,mid,a,b,n*2);
query(mid+1,r,a,b,n*2+1);
}
}

int main()
{
int N,Q,i;
int a,b,l,r;
while(scanf("%d%d",&N,&Q)>0)
{
for(i=1;i<=N;i++)
scanf("%d",&Date[i]);
build(1,N,1);
while(Q--)
{
scanf("%d%d",&l,&r);
a=MAX;b=-1;
query(l,r,&a,&b,1);
printf("%d\n",b-a);
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: