POJ 3264 Balanced Lineup

题意:给n个数字,有q个查询,每个查询给出两个数l、r,求区间[l,r]内最大值与最小值的差

解题思路:线段树.由于数据量很大,直接模拟一定会超时,所以要用线段树维护每个区间的最大值和最小值,直接套模板

代码:

 

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

#define INF 0x3f3f3f3f
const int maxn=50000+5;
int arr[maxn];
struct SegTreeNode
{
    int valx,vald;
}segTree[maxn*4];
void build(int root,int istart,int iend)
{
    if(istart==iend)
    {
        segTree[root].valx=arr[istart];
        segTree[root].vald=arr[istart];
    }
    else
    {
        int mid=(istart+iend)/2;
        build(root*2,istart,mid);
        build(root*2+1,mid+1,iend);
        segTree[root].valx=min(segTree[root*2].valx,segTree[root*2+1].valx);
        segTree[root].vald=max(segTree[root*2].vald,segTree[root*2+1].vald);
    }
}
int query1(int root,int nstart,int nend,int qstart,int qend)
{
    if(qstart>nend||qend=nend)return segTree[root].valx;
    int mid=(nstart+nend)/2;
    return min(query1(root*2,nstart,mid,qstart,qend),query1(root*2+1,mid+1,nend,qstart,qend));
}
int query2(int root,int nstart,int nend,int qstart,int qend)
{
    if(qstart>nend||qend=nend)return segTree[root].vald;
    int mid=(nstart+nend)/2;
    return max(query2(root*2,nstart,mid,qstart,qend),query2(root*2+1,mid+1,nend,qstart,qend));
}
void updateOne(int root,int nstart,int nend,int index,int addval)
{
    if(nstart==nend)
    {
        if(index==nstart)
        {
            segTree[root].valx+=addval;
            segTree[root].vald+=addval;
            return ;
        }
    }
    int mid=(nstart+nend)/2;
    if(index<=mid)updateOne(root*2,nstart,mid,index,addval);
    else updateOne(root*2+1,mid+1,nend,index,addval);
    segTree[root].valx=min(segTree[root*2].valx,segTree[root*2+1].valx);
    segTree[root].vald=max(segTree[root*2].vald,segTree[root*2+1].vald);
}
int n,q;
int main()
{
    while(scanf("%d%d",&n,&q)==2)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&arr[i]);
        }
        build(1,1,n);
        int l,r;
        for(int i=0;i

 

 

 

你可能感兴趣的:(OJ刷题)