BZOJ 1067 [SCOI2007]降雨量

Posted Visitor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1067 [SCOI2007]降雨量相关的知识,希望对你有一定的参考价值。

【链接】 我是链接,点我呀:)
【题意】


在这里输入题意

【题解】

/*
    y x

    a[x]<=a[y]

    a[y+1..x-1]<a[x]

    先查找y这个年份的降雨量有没有给出->bo1。
    再查找x这个年份的降雨量有没有给出->bo2
    如果!bo1 && !bo2
    那么直接输出maybe

    如果!bo1或者!bo2
        如果y没找到,那么看看y+1..x-1内的最大值是不是小于a[x]
        是的话,那么输出maybe
        否则输出false

        如果x没找到,还是一样,看看y+1..x-1内的最大值是不是小于a[y]
        (因为a[x]最大为a[y])
        是的话,那么输出maybe
        否则输出false

    如果bo1 且 bo2
        那么先判断a[y]>=a[x]是否成立。
            不成立的话,直接输出false

        然后看看x+1..y-1之间的最大值是多少。
            如果最大值大于等于a[x],直接输出false
        否则,看看x+1,y-1之间已知的降雨量个数是否为y-x-1
            是的话true
            否则,maybe
*/

【代码】

#include <bits/stdc++.h>
using namespace std;

const int N = 5e4;

const int MAXL = 20;
const int INF = 0x3f3f3f3f;
int n,m,a[N+10];
map<int,int> dic;

struct abc{
    int pre2[MAXL+5],need[N+10];
    int fmax[N+10][MAXL+5];

    void init(int n)
    {
        pre2[0] = 1;
        for (int i = 1;i <= MAXL;i++)
        {
            pre2[i] = pre2[i-1]<<1;
        }
        need[1] = 0; need[2] = 1;
        int temp = 2;
        for (int i = 3; i <= n; i++)
            if (pre2[temp] == i)
                need[i] = need[i - 1] + 1, temp++;
            else
                need[i] = need[i - 1];
    }

    void getst(int *a,int n)
    {
        for (int i = 1;i <= n;i++)
            fmax[i][0] = dic[a[i]];


        for (int l = 1;pre2[l]<=n;l++)
            for (int i = 1;i <= n;i++){
                if (i+pre2[l]-1<=n)
                    fmax[i][l] = max(fmax[i][l-1],fmax[i+pre2[l-1]][l-1]);
            }

    }

    int getmax(int l,int r)
    {
        int len = need[r-l+1];
        return max(fmax[l][len],fmax[r-pre2[len]+1][len]);
    }

}ST;

int main()
{
    //freopen("D:\\rush.txt","r",stdin);
    scanf("%d",&n);
    for (int i = 1;i <= n;i++){
        int ri;
        scanf("%d%d",&a[i],&ri);
        dic[a[i]] = ri;
    }
    sort(a+1,a+1+n);
    ST.init(n);
    ST.getst(a,n);

    scanf("%d",&m);
    for (int i = 1;i <= m;i++){
        int x,y;
        scanf("%d%d",&y,&x);
        bool bo1,bo2;
        bo1 = bo2 = true;
        if (dic.find(y)==dic.end()) bo1 = false;
        if (dic.find(x)==dic.end()) bo2 = false;
        if (!bo1 && !bo2){
            puts("maybe");
        }else if (!bo1 || !bo2){
            int num;
            if (bo1) num = dic[y];else num = dic[x];
            int l = upper_bound(a+1,a+1+n,y)-a;
            int r = lower_bound(a+1,a+1+n,x)-a;
            r--;
            if (l>r || ST.getmax(l,r)<num){
                puts("maybe");
            }else puts("false");
        }else{
            if (dic[y]<dic[x]){
                puts("false");
            }else{
                int l = lower_bound(a+1,a+1+n,y)-a;
                int r = lower_bound(a+1,a+1+n,x)-a;
                l++,r--;
                if (l>r || ST.getmax(l,r)<dic[x]){
                    if (l>r){
                        if (x==y+1)
                            puts("true");
                        else
                            puts("maybe");
                    }else{
                        if (x-y-1==(r-l+1)){
                            puts("true");
                        }else{
                            puts("maybe");
                        }
                    }

                }else{
                    puts("false");
                }
            }
        }
    }
    return 0;
}

以上是关于BZOJ 1067 [SCOI2007]降雨量的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1067: [SCOI2007]降雨量

BZOJ 1067: [SCOI2007]降雨量

bzoj 1067: [SCOI2007]降雨量

BZOJ1067SCOI2007降雨量(线段树)

[BZOJ 1067][SCOI2007]降雨量

BZOJ 1067 [SCOI2007]降雨量