POJ3264[线段树]
就是说有一个序列长度为n,q次询问,询问区间内最大值与最小值的差
可以说是经典的线段树板子题。。
第一次写线段树,有些漏洞请大家及时提出.
线段树大概就是将元素分配,蒟蒻语文不好,大家请看图
【图片来源:百度百科‘线段树’】
大概是这个样子,可以将时间复杂度压缩到O(nlogn)【特别快对不对】
代码这里↓
#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;
}