【BZOJ 1067】 [SCOI2007]降雨量

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

在这里输入题意

【题解】

```cpp /* 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

*/

</font>

<font color = black size = 6> 【代码】</font>
```cpp
#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;
}

posted @ 2018-03-13 11:27  AWCXV  阅读(108)  评论(0编辑  收藏  举报