zoukankan      html  css  js  c++  java
  • 【线段树 细节题】bzoj1067: [SCOI2007]降雨量

    主要还是细节分析;线段树作为工具

    Description

      我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意
    Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,
    则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未
    知,有的说法是可能正确也可以不正确的。

    Input

      输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小
    到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是
    自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。

    Output

      对于每一个询问,输出true,false或者maybe。

    Sample Input

    6
    2002 4920
    2003 5901
    2004 2832
    2005 3890
    2007 5609
    2008 3024
    5
    2002 2005
    2003 2005
    2002 2007
    2003 2007
    2005 2008

    Sample Output

    false
    true
    false
    maybe
    false

    HINT

    100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9


    题目分析

    题意很简单,但是一道需要细细思考的细节题。

    具体的思路,挂一个很详细的博客好了题解 P2471 【[SCOI2007]降雨量】

    至于具体实现我用了离散化,然后用线段树查询(x,y)区间内的最值。

      1 #include<bits/stdc++.h>
      2 const int maxn = 50035;
      3 
      4 struct QRs
      5 {
      6     int x,y;
      7 }qr[10035];
      8 struct node
      9 {
     10     int x,val;
     11 }a[maxn];
     12 int n,m;
     13 int tot[100035],t[100035],cnt;
     14 int val[100035],f[400035];
     15 
     16 int read()
     17 {
     18     char ch = getchar();
     19     int num = 0;
     20     bool fl = 0;
     21     for (; !isdigit(ch); ch = getchar())
     22         if (ch=='-') fl = 1;
     23     for (; isdigit(ch); ch = getchar())
     24         num = (num<<1)+(num<<3)+ch-48;
     25     if (fl) num = -num;
     26     return num;
     27 }
     28 void pushup(int x)
     29 {
     30     f[x] = std::max(f[x<<1], f[x<<1|1]);
     31 }
     32 void build(int rt, int l, int r)
     33 {
     34     if (l==r){
     35         f[rt] = val[l];
     36         return;
     37     }
     38     int mid = (l+r)>>1;
     39     build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
     40     pushup(rt);
     41 }
     42 int query(int rt, int L, int R, int l, int r)
     43 {
     44     if (L > R) return 0;
     45     if (L <= l&&r <= R) return f[rt];
     46     int mid = (l+r)>>1, ret = 0;
     47     if (L <= mid) ret = query(rt<<1, L, R, l, mid);
     48     if (R > mid)
     49         ret = std::max(ret, query(rt<<1|1, L, R, mid+1, r));
     50     return ret;
     51 }
     52 int main()
     53 {
     54     n = read();
     55     for (int i=1; i<=n; i++)
     56         t[++cnt] = a[i].x = read(), a[i].val = read();
     57     m = read();
     58     for (int i=1; i<=m; i++)
     59         t[++cnt] = qr[i].x = read(), t[++cnt] = qr[i].y = read(), t[++cnt] = qr[i].y-1, t[++cnt] = qr[i].x+1;
     60     std::sort(t+1, t+cnt+1);
     61     cnt = std::unique(t+1, t+cnt+1)-t-1;
     62     int pre = 0;
     63     for (int i=1; i<=n; i++)
     64     {
     65         int tt = std::lower_bound(t+1, t+cnt+1, a[i].x)-t;
     66         val[tt] = a[i].val, tot[tt] = tot[pre]+1, pre = tt;
     67     }
     68     build(1, 1, cnt);
     69     for (int i=1; i<=m; i++)
     70     {
     71         int x = std::lower_bound(t+1, t+cnt+1, qr[i].x)-t;
     72         int y = std::lower_bound(t+1, t+cnt+1, qr[i].y)-t;
     73         int dex = std::lower_bound(t+1, t+cnt+1, qr[i].x+1)-t;
     74         int dey = std::lower_bound(t+1, t+cnt+1, qr[i].y-1)-t;
     75         if (val[x]&&val[y]){
     76             if (val[x] < val[y]) puts("false");
     77             else{
     78                 bool exCheck = query(1, dex, dey, 1, cnt)<val[y];
     79                 if (!exCheck) puts("false");
     80                 else{
     81                     exCheck = exCheck&&((tot[y]-tot[x])==(qr[i].y-qr[i].x));
     82                     if (!exCheck) puts("maybe");
     83                     else puts("true");
     84                 }
     85             }
     86             continue;
     87         }
     88         if ((!val[x])&&(!val[y])) puts("maybe");
     89         else{
     90             int secMx = query(1, dex, dey, 1, cnt);
     91             if (!secMx){
     92                 puts("maybe");
     93                 continue;
     94             }
     95             if (val[x]){
     96                 if (secMx >= val[x]) puts("false");
     97                 else puts("maybe");        //注意这里是maybe而不是true因为中间值未知
     98             }
     99             if (val[y]){
    100                 if (secMx >= val[y]) puts("false");
    101                 else puts("maybe");
    102             }
    103         }
    104     }
    105     return 0;
    106 }

    END

  • 相关阅读:
    HDU
    CodeForces
    CodeForces
    TensorFlow下利用MNIST训练模型并识别自己手写的数字
    李宏毅机器学习笔记2:Gradient Descent(附带详细的原理推导过程)
    李宏毅机器学习笔记1:Regression、Error
    tensorflow相关API的学习
    解决winscp中普通用户无法上传、删除、移动文件
    2019最新最全HUSTOJ本地及云端服务器搭建(基于腾讯云服务器)
    解决Ubuntu无法进行SSH连接的问题(以及如何使用SSH)
  • 原文地址:https://www.cnblogs.com/antiquality/p/9354866.html
Copyright © 2011-2022 走看看