【北大夏令营笔记-线段树】POJ3264-Balanced Lineup

Balanced Lineup
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 32777 Accepted: 15424
Case Time Limit: 2000MS
Description

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 ≤ 200,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.

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 a response to a reply and indicates the difference in height between the tallest and shortest cow in the 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 Silver

题意:求给定Q(1<=Q<=200000)个数a1,a2...aq,多次求任意区间内ai-aj中最大数和最小数的差;
思路:线段树查询;

AC代码:

#include<stdio.h>
#include<string.h>
#define MAX_INF 9999999
#define MIN_INF -9999999
struct Node
{
   int l,r;
   int max,min;
}a[200005];
int max(int n,int m)
{
    return n>m?n:m;
}
int min(int n,int m)
{
    return n<m?n:m;
}
void Build(int n,int l,int r)
{
   a[n].l=l;
   a[n].r=r;
   a[n].max=MIN_INF;
   a[n].min=MAX_INF;
   if(l==r)
   return;
   Build(2*n,l,(l+r)/2);
   Build(2*n+1,(l+r)/2+1,r);
}
void Insert(int n,int v,int num)
{
   if(a[n].max<num) a[n].max=num;
   if(a[n].min>num) a[n].min=num;
   if(a[n].l==a[n].r)
   return;
   if(v<=(a[n].l+a[n].r)/2)
   Insert(n*2,v,num);
   else
   Insert(n*2+1,v,num);
}
int QMax(int n,int l,int r)
{
    if(a[n].l==l&&a[n].r==r)
    return a[n].max;
    if(r<=(a[n].l+a[n].r)/2)
    return QMax(n*2,l,r);
    else
    if(l>=(a[n].l+a[n].r)/2+1)
    return QMax(n*2+1,l,r);
    else
    {
        return max(QMax(n*2,l,(a[n].l+a[n].r)/2),QMax(n*2+1,(a[n].l+a[n].r)/2+1,r));
    }
}
int QMin(int n,int l,int r)
{
    if(a[n].l==l&&a[n].r==r)
    return a[n].min;
    if(r<=(a[n].l+a[n].r)/2)
    return QMin(n*2,l,r);
    else
    if(l>=(a[n].l+a[n].r)/2+1)
    return QMin(n*2+1,l,r);
    else
    {
        return min(QMin(n*2,l,(a[n].l+a[n].r)/2),QMin(n*2+1,(a[n].l+a[n].r)/2+1,r));
    }
}
void QMinus(int n,int l,int r)
{
    if(a[n].l==l&&a[n].r==r)
    {
        printf("%d\n",a[n].max-a[n].min);
    }
    else
    {
        if(r<=(a[n].l+a[n].r)/2)
        QMinus(n*2,l,r);
        else
        if(l>=(a[n].l+a[n].r)/2+1)
        QMinus(n*2+1,l,r);
        else
        {
            int m1=QMax(n*2,l,(a[n].l+a[n].r)/2);
            int m2=QMax(n*2+1,(a[n].l+a[n].r)/2+1,r);
            int m3=QMin(n*2,l,(a[n].l+a[n].r)/2);
            int m4=QMin(n*2+1,(a[n].l+a[n].r)/2+1,r);
            printf("%d\n",max(m1,m2)-min(m3,m4));
        }
    }
}
int main()
{
    int i,j,n,m,x,l,r;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        Build(1,1,n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            Insert(1,i,x);
        }
        for(i=0;i<m;i++)
        {
            scanf("%d %d",&l,&r);
            QMinus(1,l,r);
        }
    }
    return 0;
}
时间: 2024-11-08 22:33:41

【北大夏令营笔记-线段树】POJ3264-Balanced Lineup的相关文章

【北大夏令营笔记-线段树】POJ3468-A Simple Problem with Integers

A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 57993 Accepted: 17658 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of ope

【北大夏令营笔记-数学题】百练1700-Crossing River

1700:Crossing River 查看 提交 统计 提示 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the

【北大夏令营笔记-并查集】poj1988-Cube Stacking

Cube Stacking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 18401 Accepted: 6378 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with

【北大夏令营笔记-动态规划】poj1458-Common Subsequence

Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37543 Accepted: 15016 Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., x

【北大夏令营笔记-并查集】poj1611-The Suspects

The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 21517 Accepted: 10422 Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To mi

线段树和RMQ解析和模板

这几天在看RMQ的题目,但是很多RMQ的题目也可以用线段树解决... 看来两者之间有很多关系,那就都好好看吧...下面先贴出一个大牛对两者的解释.. RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题  主要方法及复杂度(处理复杂度和查询复杂度)如下:  1.朴素(即搜索) O(n)-O(n)  2.线段树(se

线段树(Segment Tree)

1.概述 线段树,也叫区间树,是一个完全二叉树,它在各个节点保存一条线段(即"子数组"),因而常用于解决数列维护问题,基本能保证每个操作的复杂度为O(lgN). 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 使用线段树可以

hdu 4614 Vases and Flowers 线段树

    比赛最后40分钟写的,线段树加二分,思路写法完全没问题,但最后提交了2次都WA了,回来后发现是模板更新lazy把0当做更新过的了,但是应该是1 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <

POJ 3468 线段树 区间更新区间查询

题意:给出一段数列,任意区间加上一个整数v,任意区间查询.给出N个数,Q次操作. 线段树的题,延迟指针不更新到底就行了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 100005 long long sum[maxn<<2],col[maxn<<2]; void