zoukankan      html  css  js  c++  java
  • Balanced Lineup POJ

    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.. NQ+1: Two integers A and B (1 ≤ A≤ B ≤ N), representing the range of cows from Ato 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

    题意:给你长度不超过50000的数组,然后问你在指定区域内最大值于最小值的差是多少。

    思路:由于要求区间类的操作,首先是线段树,而这个题就比较简单了,首先在线段树初始化时给每个节点设置两个值,分别是这个节点的最大值和最小值
    。由于数据又不是很大,因此可以写两个区间求值方法,一个求最大值,一个求最小值,在相减一下就行了。

    代码:
      1 #include <cstdio>
      2 #include <fstream>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <deque>
      6 #include <vector>
      7 #include <queue>
      8 #include <string>
      9 #include <cstring>
     10 #include <map>
     11 #include <stack>
     12 #include <set>
     13 #include <sstream>
     14 #include <iostream>
     15 #define mod 998244353
     16 #define eps 1e-6
     17 #define ll long long
     18 #define INF 0x3f3f3f3f
     19 using namespace std;
     20 
     21 struct node
     22 {
     23     //l表示左边,r表示右边
     24     int l,r,mi,ma;
     25 
     26 };
     27 node no[500000];
     28 int num[50000];
     29 
     30 //初始化
     31 //k表示当前节点的编号,l表示当前区间的左边界,r表示当前区间的右边界
     32 void build(int k,int l,int r)
     33 {
     34     no[k].l=l;
     35     no[k].r=r;
     36     //如果递归到最低点
     37     if(l==r)
     38     {
     39         no[k].mi=num[l];
     40         no[k].ma=num[l];
     41         return ;
     42     }
     43     //对半分
     44     int mid=(l+r)/2;
     45     //递归到左线段
     46     build(k*2,l,mid);
     47     //递归到右线段
     48     build(k*2+1,mid+1,r);
     49     //更新当前节点的值
     50     no[k].mi=min(no[k*2].mi,no[k*2+1].mi);
     51     no[k].ma=max(no[k*2].ma,no[k*2+1].ma);
     52 }
     53 //求区间内最小值
     54 int querymi(int k,int l,int r)
     55 {
     56     //到对应层时返回值
     57     if(no[k].l==l&&no[k].r==r)
     58     {
     59         return no[k].mi;
     60     }
     61     //取中值
     62     int mid=(no[k].l+no[k].r)/2;
     63     if(r<=mid)
     64     {
     65         return querymi(k*2,l,r);
     66     }
     67     else if(l>mid)
     68     {
     69         return querymi(k*2+1,l,r);
     70     }
     71     else
     72     {
     73         return min(querymi(k*2,l,mid),querymi(k*2+1,mid+1,r));
     74     }
     75 }
     76 //求区间内最大值
     77 int queryma(int k,int l,int r)
     78 {
     79     //到对应层时返回值
     80     if(no[k].l==l&&no[k].r==r)
     81     {
     82         return no[k].ma;
     83     }
     84     //取中值
     85     int mid=(no[k].l+no[k].r)/2;
     86     if(r<=mid)
     87     {
     88         return queryma(k*2,l,r);
     89     }
     90     else if(l>mid)
     91     {
     92         return queryma(k*2+1,l,r);
     93     }
     94     else
     95     {
     96         return max(queryma(k*2,l,mid),queryma(k*2+1,mid+1,r));
     97     }
     98 }
     99 int main()
    100 {
    101     int q,n;
    102     scanf("%d %d",&n,&q);
    103     for(int i=1;i<=n;i++)
    104     {
    105         scanf("%d",&num[i]);
    106     }
    107     build(1,1,n);
    108     int a,b;
    109     for(int i=0;i<q;i++)
    110     {
    111         scanf("%d %d",&a,&b);
    112         printf("%d
    ",queryma(1,a,b)-querymi(1,a,b));
    113     }
    114 }


  • 相关阅读:
    Android 适配知识点
    Android Studio各种快捷功能及好用的插件
    81.Android之沉浸式状态栏攻略
    8.Android 系统状态栏沉浸式/透明化解决方案
    为开发者准备的 Android 函数库(2016 年版)
    GitHub 上 57 款最流行的开源深度学习项目
    7.Android开源项目WheelView的时间和地址联动选择对话框
    6.初探Asynctask
    5.Android消息推送机制简单例子
    让你Android开发更简单
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11808288.html
Copyright © 2011-2022 走看看