1. 程式人生 > >【BZOJ 1067】 [SCOI2007]降雨量

【BZOJ 1067】 [SCOI2007]降雨量

年份 ont const mes bits sca 判斷 num 多少

【鏈接】 我是鏈接,點我呀:)
【題意】


在這裏輸入題意

【題解】

/*
    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]降雨量