1. 程式人生 > 遊戲 >《刺客信條:英靈殿》擴充套件內容“圍攻巴黎”明日正式推出

《刺客信條:英靈殿》擴充套件內容“圍攻巴黎”明日正式推出

題目描述

我們常常會說這樣的話:“X 年是自 Y 年以來降雨量最多的”。它的含義是 X 年的降雨量不超過 Y 年,且對於任意 Y<Z<X,Z 年的降雨量嚴格小於 X 年。例如 2002,2003,2004 和 2005 年的降雨量分別為 4920,5901,2832 和 3890,則可以說“2005 年是自 2003 年以來最多的”,但不能說“2005 年是自 2002 年以來最多的”由於有些年份的降雨量未知,有的說法是可能正確也可以不正確的。題目link

思路

先判false:
1、當右端點年份確定,且中間年份最大降雨量大於等於右端點降雨量
2、當左端點年份確定,且中間年份最大降雨量大於等於左端點降雨量
3、當左右端點年份都確定,且左端點降雨量小於等於右端點降雨量
再判maybe:
1、當左右端點之差不等於左右端點年份之差(等價於年份不連續,也就是我前面所說的更好的判斷區間連續的方法)
2、左端點年份不確定
3、右端點年份不確定
(因為已經切掉false的情況了,那麼剩下的情況中可以直接照上面的判斷!)
最後判斷true

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

const int N = 50010;
int y[N], rr[N];

int n, m;
const int M = 17;

int f[N][M];//表示i開始,長度為2^j的最大值

void init() {
    for(int j=0; j<M; ++j)//長度從2^0到2^M列舉
        for(int i=1; i+(1<<j)-1<=n; ++i) {//位置從1到1+len-1<=n
            if(!j) f[i][j] = rr[i];
            else f[i][j] = max(f[i][j-1], f[i+(1<<j-1)][j-1]);//從i+2^(j-1)
        }
}

int query(int l, int r) {//下表為l~r中返回最大的數
    int len = r - l + 1;
    int k = log2(len);
    return max(f[l][k], f[r-(1<<k)+1][k]);//f[l,k], f[r-2^k,k]
}

signed main()
{
    cin>>n;
    for(int i=1; i<=n; ++i) {
        scanf("%lld%lld", &y[i], &rr[i]);
    }
    
    init();
    
    cin>>m;
    while(m--) {
        int y1, y2;
        scanf("%lld%lld", &y1, &y2);
        if(y1>=y2){printf("false\n");continue;}
        int st=lower_bound(y+1,y+n+1,y1)-y,ed=lower_bound(y+1,y+n+1,y2)-y;
        bool fl,fr;int op=0;
        fl=y[st]==y1,fr=y[ed]==y2;
        if(!fl)st--;
        if(st+1<=ed-1)op=query(st+1,ed-1);
        if((op>=rr[ed]&&fr)||(rr[st]<rr[ed]&&fl&&fr)||(op>=rr[st]&&fl))printf("false\n");
        else if(ed-st!=y[ed]-y[st]||!fr||!fl)printf("maybe\n");
        else printf("true\n");
    }
    return 0;
}