POJ3264[线段树]

就是说有一个序列长度为n,q次询问,询问区间内最大值与最小值的差

可以说是经典的线段树板子题。。

第一次写线段树,有些漏洞请大家及时提出.

线段树大概就是将元素分配,蒟蒻语文不好,大家请看图

【图片来源:百度百科‘线段树’】

大概是这个样子,可以将时间复杂度压缩到O(nlogn)【特别快对不对】

点这里这里A题

 

代码这里↓

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;


const int MAXV=50100;


struct Node
{
int mid;
int min;
int max;
int left;
int right;
}a[600100];


int h[MAXV],n,q,ansmin,ansmax;


void maketree(int x)
{
if(a[x].min==0&&a[x].max==0)
{
a[x].min=10000000;
a[x].max=-1;
}

if(a[x].left==a[x].right)
{
a[x].min=h[a[x].left];
a[x].max=h[a[x].left];
return;
}

a[x].mid=(a[x].left+a[x].right)/2;
a[2*x].left=a[x].left;
a[2*x].right=a[x].mid;
maketree(2*x);
a[2*x+1].left=a[x].mid+1;
a[2*x+1].right=a[x].right;
maketree(2*x+1);

a[x].min=min(a[2*x].min,a[2*x+1].min);
a[x].max=max(a[2*x].max,a[2*x+1].max);
}


void dfs(int l,int r,int x)
{

if(l==a[x].left&&r==a[x].right)
{
ansmin=min(ansmin,a[x].min);
ansmax=max(ansmax,a[x].max);
return;
}
if(l<=a[2*x].right)
{
if(r<=a[2*x].right)
{
dfs(l,r,2*x);
}
else
{
dfs(l,a[2*x].right,2*x);
dfs(a[2*x+1].left,r,2*x+1);
}
}
else
{
dfs(l,r,2*x+1);
}
}


int main()
{
int i,j,k,w,s,x,d,l,r;

scanf("%d%d",&n,&q);

for(i=1;i<=n;i++)
{
scanf("%d",&h[i]);
}

a[1].left=1;
a[1].right=n;
maketree(1);

for(i=0;i<q;i++)
{
scanf("%d%d",&l,&r);
ansmin=100000000;
ansmax=-1;
dfs(l,r,0);

printf("%d\n",ansmax-ansmin);
}
return 0;
}

 

posted @ 2017-08-13 15:21  寒雨微凝  阅读(101)  评论(0编辑  收藏  举报