• BZOJ 1067:[SCOI2007]降雨量(RMQ+思维)


    http://www.lydsy.com/JudgeOnline/problem.php?id=1067

    题意:……

    思路:首先我们开一个数组记录年份,一个记录降雨量,因为年份是按升序排列的,所以我们在每个询问找下标的时候可以二分搜索,然后对于每个询问我们是要寻找区间的最大值,因此我们可以使用ST表来做。比较麻烦的是判断三种答案的情况,做了一个下午。假设询问输入的是X和Y(X < Y)接下来分为四种情况:

    1、X是已知,Y是已知。那么这是最容易想到的情况。

    1-1、如果在[X+1,Y-1]区间中存在大于等于Y的降雨量,或者Y的降雨量大于X的降雨量,那么就输出false。

    1-2、否则如果[X+1,Y-1]中存在未知年份,那么就输出maybe。

    1-3、否则输出true。

    2、X是已知,Y是未知。

    2-1、如果在[X+1,Y]区间中存在大于等于X的降雨量,那么输出false。

    2-2、否则输出maybe。

    这里要注意如果X+1 > Y的情况,那么肯定是输出maybe的。要特判一下。(坑了好久)

    3、X是未知,Y是已知。

    3-1、如果在[X,Y-1]区间中存在大于等于Y的降雨量,那么输出false。

    3-2、否则输出maybe。

    4、X是未知,Y是未知。

    4-1、直接输出maybe。

    这里lower_bound()返回的是大于等于x的下标,upper_bound() - 1返回的是小于等于x的下标。

    判断存在不存在就直接是二分后的下标和本身是不是相等的,而不用用到map这样的数据结构判断。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <iostream>
     6 using namespace std;
     7 #define N 50010
     8 #define INF 0x3f3f3f3f
     9 
    10 int n, year[N], fall[N], dp[N][30];
    11 
    12 void RMQ_Init() {
    13     for(int i = 1; i <= n; i++) dp[i][0] = fall[i];
    14     int ed = (int)(log(n) / log(2.0));
    15     for(int j = 1; j <= ed; j++)
    16         for(int i = 1; i + (1 << j) - 1 <= n; i++)
    17             dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
    18 }
    19 
    20 int RMQ_Query(int l, int r) {
    21     if(l > r) return -INF; // !!!!!
    22     int ed = (int)(log(r - l + 1.0) / log(2.0));
    23     return max(dp[l][ed], dp[r-(1<<ed)+1][ed]);
    24 }
    25 
    26 int main() {
    27     int q;
    28     while(~scanf("%d", &n)) {
    29         for(int i = 1; i <= n; i++) scanf("%d%d", &year[i], &fall[i]);
    30         RMQ_Init();
    31         scanf("%d", &q);
    32         while(q--) {
    33             int l, r; scanf("%d%d", &l, &r);
    34             if(l > r) { puts("false"); continue; }
    35             int lid = lower_bound(year + 1, year + 1 + n, l) - year;
    36             int rid = upper_bound(year + 1, year + 1 + n, r) - year - 1;
    37             int ans, res;
    38             if(year[lid] != l) {
    39                 ans = RMQ_Query(lid, rid - 1);
    40                 if(year[rid] != r) puts("maybe");
    41                 else if(ans >= fall[rid]) puts("false");
    42                 else puts("maybe");
    43             } else if(year[rid] != r) {
    44                 ans = RMQ_Query(lid + 1, rid);
    45                 if(ans >= fall[lid]) puts("false");
    46                 else puts("maybe");
    47             } else {
    48                 ans = RMQ_Query(lid + 1, rid - 1);
    49                 if(fall[rid] <= ans || fall[lid] < fall[rid]) puts("false");
    50                 else if(rid - lid != year[rid] - year[lid]) puts("maybe");
    51                 else puts("true");
    52             }
    53         }
    54     }
    55     return 0;
    56 }
    57 
    58 /*
    59 2
    60 2000 4000
    61 2005 4500
    62 1
    63 2005 2010
    64 
    65 maybe
    66 */
  • 相关阅读:
    思科交换机端口安全配置
    华为交换机端口安全配置
    多行文本出现省略号必备的条件(面试题)
    单行文本出现省略号必备的条件(面试题)
    让多个元素在一行显示的方法和技巧(面试题)
    overflow的多个作用
    雪碧图的使用和制作技巧
    列举background属性的8个属性值(面试题)
    background-origin设置背景图像的参考原点(位置)
    background-clip设置对象的背景图像向外裁剪的区域
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6344749.html
Copyright © 2020-2023  润新知