洛谷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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值