洛谷P2311 loidc,想想看

題目背景

話說loidc現在正在家閒的無聊,這天loidc正在觀看比賽,他突然很有興趣想了解一段時間內中國隊獲得金牌的情況。

題目描述

還有一點,loidc有特殊能力,可以預知未來,他可以準確的猜到中國隊在某一個單位時間內獲得的金牌數。但是,還有但是!由於工作量太大,再加上猜金牌要費很多的體力,所以他無法準確的計算出一段時間內獲得的金牌數最大的單位時間是哪個,就因爲這樣loidc很鬱悶。他思索來思索去就想到了你,因爲他知道你是個OIer,所以他對你呵呵一笑就把問題交給你了,loidc希望你能在1S內得出答案

輸入輸出格式

輸入格式:

第一行一個n表示有n個時間段。
接下來一行有n個數ai,ai表示loidc猜到的中國隊在第i個時間段內獲得的金牌數。
然後,第三行有一個數m,表示loidc有個問題。
接下來有m行,每行有2個數分別爲xi yi,表示要詢問在時間段[xi,yi]內中國隊獲得金牌數最大的是哪個單位時間。
loidc有一個習慣,他問問題是有先後的,也就是說後一個問題總是在前一個問題之後提出的。
注意對於第i個提問和第i+1個提問嚴格的有xi<=xi+1,yi<=yi+1。

輸出格式:

一共m行,每行一個ki,表示第i個詢問的答案。

輸入輸出樣例

輸入樣例

5
2 3 4 5 6
1 1
1 2
2 3
3 4
4 5

輸出樣例

1
2
3
4
5

說明

30%: n<=1000 m<=1000
100%: n<=100000 m<=100000
其他有關輸入輸出均小於maxlongint。
數據保證ai沒有相同的。
雖然詢問的性質看起來是有巧解,但我已經放棄了思考,選擇線段樹qwq
代碼如下

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int num[1010010];
int t[1011000];
struct xd_tree
{
    int l,r,p;
    int add,max;
}tree[1010010*4];
void build(int p,int l,int r)
{
    tree[p].l = l , tree[p].r = r;
    if(l == r)
    {
        tree[p].max = num[l];
        return ;
    }
    int mid = ( l + r ) >> 1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    tree[p].max = max(tree[p*2].max,tree[p*2+1].max);
}
int ask(int p,int l,int r)
{
    if(tree[p].l >= l && tree[p].r <= r)
        return tree[p].max;
    int ans = 0;
    int mid = (tree[p].l + tree[p].r) >> 1;
    if(l <= mid)
        ans = max(ans,ask(p*2,l,r));
    if(r > mid)
        ans = max(ans,ask(p*2+1,l,r));
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 1 ; i <= n ; i ++)
        scanf("%d",&num[i]) , t[num[i]] = i;
    build(1,1,n);
    int q;
    scanf("%d",&q);
    for(int i = 1 ; i <= q ; i ++)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        cout<<t[ask(1,l,r)]<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章