poj 3264

来源:互联网 发布:高校教务管理系统源码 编辑:程序博客网 时间:2024/06/03 23:00

题目概述

给定N个数,编号1到N,进行Q次询问,回答编号在询问区间内的数的最大值和最小值的差
询问区间的左边界总是不大于右边界

时限

case: 2000ms/2110ms
total: 5000ms/15000ms

输入

第一行两个正整数N,Q,其后N行,每行一个正整数,其后Q行,每行两个正整数,代表询问区间,输入到EOF为止

限制

1<=N<=50000;1<=Q<=200000;1<=每个数<=1e6

输出

每行一个数,为询问的回答

样例输入

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

样例输出

6
3
0

讨论

线段树,求最值差,实质都差不多,只是为了回顾线段树而再做一次旧题,建树的时候可以顺手赋值,省去了modify函数
然而运行速度还是那么慢

题解状态

2412K,1985MS,C++,1347B

题解代码

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define INF 0x3f3f3f3f#define MAXN 50003#define memset0(a) memset(a,0,sizeof(a))struct it//item 树节点的结构{    int l, r;//left right 节点指代的区间    int least, most;//最小值 最大值}its[MAXN * 4];//仍然是4倍大小int N, Q;//数的总数 询问数int nums[MAXN];//数的原始数据 临时存放而已void build(int i, int l, int r)//建树 i为内部参数 递归时用 l,r为构造区间{    its[i].l = l, its[i].r = r;    if (l == r) {//到单点时停止        its[i].least = its[i].most = nums[l];        return;    }    build(i * 2, l, (l + r) / 2);    build(i * 2 + 1, (l + r) / 2 + 1, r);//否则递归构造左右子树    its[i].least = min(its[i * 2].least, its[i * 2 + 1].least);    its[i].most = max(its[i * 2].most, its[i * 2 + 1].most);//比较子树得到最值 初始化}void query(int i, int l, int r, int &least, int &most)//查询 利用传引用返回结果{    if (l <= its[i].l&&r >= its[i].r) {//包含在内则直接返回        least = its[i].least, most = its[i].most;        return;    }    else if (l > its[i].r || r < its[i].l) {//在外面则返回一个不可能值        least = INF, most = -INF;        return;    }    int leastl, leastr, mostl, mostr;    query(i * 2, l, r, leastl, mostl);    query(i * 2 + 1, l, r, leastr, mostr);//递归查询子树    least = min(leastl, leastr);    most = max(mostl, mostr);//比较返回结果}void fun(){    for (int p = 1; p <= N; p++)        scanf("%d", &nums[p]);//input    build(1, 1, N);//利用nums数组进行建树    for (int p = 0; p < Q; p++) {        int a, b;        scanf("%d%d", &a, &b);//input        int least, most;        query(1, a, b, least, most);        printf("%d\n", most - least);//output    }}int main(void){    //freopen("vs_cin.txt", "r", stdin);    //freopen("vs_cout.txt", "w", stdout);    while (~scanf("%d%d", &N, &Q))//input        fun();}

EOF

0 0
原创粉丝点击