sdutoj 3302 效率至上

题目链接:点击打开链接

题目大意:


给出一个数目为n的非有序序列,然后有m次查询.对于每次查询输入两个正整数l,r请输出区间[l,r]的最大值与最小值的差值

输入

  第一行:输入两个正整数 n,m    (1<=n<=50000,  1<=m<=200000  )

第二行:输入n个整数  大小范围为[1,100000];

接下来的m,每次两个正整数l,r (1<=l<=r<=n);

输出

  输出区间 [l,r] 最大值与最小值的差值 .

///思路:线段树的区间最值查找 

#include <iostream>  
35.#include<cstdio>  
36.  
37.using namespace std;  
38.  
39.void build(int node,int k,int e,int a[],int b[])  
40.{  
41.    if(k==e)b[node]=a[k];  
42.    else  
43.    {  
44.        build(2*node,k,(k+e)/2,a,b);  
45.        build(2*node+1,(k+e)/2+1,e,a,b);  
46.        if(b[2*node]<=b[2*node+1])  
47.            b[node]=b[2*node];  
48.        else b[node]=b[node*2+1];  
49.    }  
50.}  
51.void build2(int node,int k,int e,int a[],int b[])  
52.{  
53.    if(k==e)b[node]=a[k];  
54.    else  
55.    {  
56.        build2(2*node,k,(k+e)/2,a,b);  
57.        build2(2*node+1,(k+e)/2+1,e,a,b);  
58.        if(b[2*node]>=b[2*node+1])  
59.            b[node]=b[2*node];  
60.        else  
61.            b[node]=b[node*2+1];  
62.    }  
63.}  
64.int finde(int node,int k,int e,int a[],int b[],int l,int r)  
65.{  
66.    int p1,p2;  
67.    if(l>e||r<k)return -1;  
68.    if(l<=k&&r>=e)return b[node];  
69.    p1=finde(2*node,k,(k+e)/2,a,b,l,r);  
70.    p2=finde(2*node+1,(k+e)/2+1,e,a,b,l,r);  
71.    if(p1==-1)return p2;  
72.    if(p2==-1)return p1;  
73.    if(p1<=p2)return p1;  
74.    return p2;  
75.}  
76.int finde2(int node,int k,int e,int a[],int b[],int l,int r)  
77.{  
78.    int p1,p2;  
79.    if(l>e||r<k)return -1;  
80.    if(l<=k&&r>=e)return b[node];  
81.    p1=finde2(2*node,k,(k+e)/2,a,b,l,r);  
82.    p2=finde2(2*node+1,(k+e)/2+1,e,a,b,l,r);  
83.    if(p1==-1)return p2;  
84.    if(p2==-1)return p1;  
85.    if(p1<=p2)return p2;  
86.    return p1;  
87.}  
88.int main()  
89.{  
90.    int a[50000];  
91.    int  b[200100];  
92.    int c[200100];  
93.    int n,m;  
94.    scanf("%d%d",&n,&m);  
95.    for(int i=1; i<=n; i++)  
96.    {  
97.        scanf("%d",&a[i]);  
98.    }  
99.    build(1,1,n,a,b);  
100.    build2(1,1,n,a,c);  
101.    int l,r;  
102.    for(int i=0; i<m; i++)  
103.    {  
104.        scanf("%d%d",&l,&r);  
105.        int mi=finde(1,1,n,a,b,l,r);  
106.        int mx=finde2(1,1,n,a,c,l,r);  
107.        printf("%d\n",mx-mi);  
108.  
109.    }  
110.    return 0;  
111.}  
112.   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值