关闭

TOJ 2762.Balanced Lineup

标签: toj线段树
56人阅读 评论(0) 收藏 举报
分类:

题目链接:http://acm.tju.edu.cn/toj/showp2762.html


2762.   Balanced Lineup
Time Limit: 5.0 Seconds   Memory Limit: 65536K
Total Runs: 1458   Accepted Runs: 544    Multiple test files



For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun, they should not differ too much in height.

Farmer John has made a list of Q (1 ≤ Q ≤ 180,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

Note: on the largest test case, I/O takes up the majority of the runtime.

Input

* Line 1 : Two space-separated integers, N and Q.

* Lines 2 .. N + 1 : Line i + 1 contains a single integer that is the height of cow i

* Lines N + 2 .. N + Q + 1: Two integers A and B ( 1 ≤ A ≤ B ≤ N ), representing the range of cows from A to B inclusive.

Output

* Lines 1 .. Q : Each line contains a single integer that is an answer to an input query and tells the difference in height between the tallest and shortest cow in the input range.

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0


Source: USACO 2007 January Competition
Submit   List    Runs   Forum   Statistics



作者:kuangbin(转载请注明出处,谢谢!!)

更多详细文章,请访问博客:www.cnblogs.com/kuangbin

 

ACM POJ 3264 Balanced Lineup

这到题目是线段树的练习题目。

很简单,练练手!!

AC程序:

复制代码
/*
POJ 3264  Balanced Lineup
题目意思:给定Q(1<=Q<=200000)个数A1,A2,```,AQ,
多次求任一区间Ai-Aj中最大数和最小数的差 
*/
#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAXN 200005
#define INF 10000000
int nMax,nMin;//记录最大最小值 
struct Node
{
    int l,r;//区间的左右端点 
    int nMin,nMax;//区间的最小值和最大值 
}segTree[MAXN*3];
int a[MAXN];
void Build(int i,int l,int r)//在结点i上建立区间为(l,r)
{
    segTree[i].l=l;
    segTree[i].r=r;
    if(l==r)//叶子结点 
    {
        segTree[i].nMin=segTree[i].nMax=a[l];
        return;
    } 
    int mid=(l+r)>>1;
    Build(i<<1,l,mid);
    Build(i<<1|1,mid+1,r);
    segTree[i].nMin=min(segTree[i<<1].nMin,segTree[i<<1|1].nMin);
    segTree[i].nMax=max(segTree[i<<1].nMax,segTree[i<<1|1].nMax);   
}
void Query(int i,int l,int r)//查询结点i上l-r的最大值和最小值
{
    if(segTree[i].nMax<=nMax&&segTree[i].nMin>=nMin)  return;
    if(segTree[i].l==l&&segTree[i].r==r)
    {
        nMax=max(segTree[i].nMax,nMax);
        nMin=min(segTree[i].nMin,nMin);
        return;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if(r<=mid)   Query(i<<1,l,r);
    else if(l>mid)  Query(i<<1|1,l,r);
    else
    {
        Query(i<<1,l,mid);
        Query(i<<1|1,mid+1,r);
    }      
}
int main()
{
    int n,q;
    int l,r;
    int i;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        for(i=1;i<=n;i++)
          scanf("%d",&a[i]);
        Build(1,1,n);
        for(i=1;i<=q;i++)
        {
            scanf("%d%d",&l,&r);
            nMax=-INF;nMin=INF;
            Query(1,l,r);
            printf("%d\n",nMax-nMin);
        }    
    }  
    return 0;  
} 
复制代码

另外附一参考程序:

复制代码
#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;
#define MY_MIN  99999999
#define MY_MAX  -99999999


struct CNode
{
    int L,R;
    int nMin,nMax;
    CNode * pLeft, * pRight;
};
int nMax, nMin;
CNode Tree[1000000];
//CNode Tree[20];
int nCount = 0;
void BuildTree(CNode * pRoot, int L,int R)
{
    pRoot->L = L;
    pRoot->R = R;
    
    pRoot->nMin = MY_MIN;
    pRoot->nMax = MY_MAX;

    if ( L != R) {
        nCount ++;
        pRoot->pLeft = Tree + nCount;
        nCount ++;
        pRoot->pRight = Tree + nCount;
        BuildTree( pRoot->pLeft, L, ( L + R )/2);
        BuildTree( pRoot->pRight, (L + R) / 2 + 1,R);
    }
}
void Insert( CNode * pRoot , int i,int v)
{
    if( pRoot->L == i &&  pRoot->R == i ) {
        pRoot->nMin = pRoot->nMax = v;
        return;
    }
    pRoot->nMin = _cpp_min(pRoot->nMin,v);
    pRoot->nMax = _cpp_max(pRoot->nMax,v);
    if( i <= (pRoot->L + pRoot->R )/2 )
        Insert( pRoot->pLeft,i,v);
    else
        Insert( pRoot->pRight,i,v);
}
void Query(CNode * pRoot, int s, int e)
{
    if( pRoot->nMin >= nMin && pRoot->nMax <= nMax )
        return;
    if( s == pRoot->L && e == pRoot->R) {
        nMin = _cpp_min(pRoot->nMin,nMin);
        nMax = _cpp_max(pRoot->nMax,nMax);
        return ;
    }
    if( e <=  (pRoot->L + pRoot->R) / 2 )
        Query(pRoot->pLeft, s,e);
    else if( s >= (pRoot->L + pRoot->R) / 2 + 1)
        Query(pRoot->pRight, s,e);
    else {
        Query(pRoot->pLeft, s,(pRoot->L + pRoot->R) / 2);
        Query(pRoot->pRight, (pRoot->L + pRoot->R) / 2 + 1 ,e);
    }
}
int main()
{
    int n,q,h;
    int i,j,k;
    scanf("%d%d",&n,&q);
    nCount = 0;
    BuildTree(Tree,1,n);    
    for( i = 1;i <= n;i ++ ) {
        scanf("%d",&h);
        Insert( Tree,i,h);
    }
    for( i = 0;i < q;i ++ ) {
        int s,e;
        scanf("%d%d", &s,&e);
        nMax = MY_MAX;
        nMin = MY_MIN;
        Query(Tree,s,e);
        printf("%d\n",nMax - nMin);
    }
    return 0;
}

0
0

猜你在找
【直播】计算机视觉原理及实战——屈教授
【套餐】深度学习入门视频课程——唐宇迪
【套餐】Hadoop生态系统零基础入门
【套餐】嵌入式Linux C编程基础
【套餐】2017软考系统集成项目——任铄
【套餐】Android 5.x顶级视频课程——李宁
【直播】广义线性模型及其应用——李科
【直播】从0到1 区块链的概念到实践
【直播】机器学习之凸优化——马博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10174次
    • 积分:1295
    • 等级:
    • 排名:千里之外
    • 原创:125篇
    • 转载:8篇
    • 译文:0篇
    • 评论:0条
    文章分类