题目描述

老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。

输入格式

输入中第一行有两个数m,n表示有m(m<=100000)笔账,n表示有n个问题,n<=100000。

第二行为m个数,分别是账目的钱数

后面n行分别是n个问题,每行有2个数字说明开始结束的账目编号。

输出格式

输出文件中为每个问题的答案。具体查看样例。

输入输出样例

输入 #1
10 3
1 2 3 4 5 6 7 8 9 10
2 7
3 9
1 10
输出 #1
2 3 1

题解

这是一道线段树的模板题目。我参考的线段树模板来自:https://baijiahao.baidu.com/s?id=1605870136961096251&wfr=spider&for=pc。原来的模板是线段区间求和,现在改为区间求最小值。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <math.h>
 4 #include <algorithm>
 5 #include <string.h>
 6 #define ll long long
 7
 8 const int MAXN = 1000001;
 9
10 using namespace std;
11
12 ll n, m, a[MAXN], ans[MAXN<<2], tag[MAXN<<2];
13
14 ll ls(ll x)
15 {
16     return x<<1;
17 }
18
19 ll rs(ll x)
20 {
21     return x<<1|1;
22 }
23
24 void push_up(ll p)
25 {
26     ans[p] = min(ans[ls(p)], ans[rs(p)]);
27 }
28
29 void build(ll p, ll l, ll r)
30 {
31     tag[p] = 0;
32     if(l == r)
33  {
34   ans[p] = a[l];
35   return;
36  }
37     ll mid = (l + r) >> 1;
38     build(ls(p), l, mid);
39     build(rs(p), mid + 1, r);
40     push_up(p);
41 }
42
43 void f(ll p, ll l, ll r, ll k)
44 {
45     tag[p] = tag[p] + k;
46     ans[p] = ans[p] + k * (r - l + 1);
47 }
48
49 void push_down(ll p, ll l, ll r)
50 {
51     ll mid = (l + r)>>1;
52     f(ls(p), l, mid, tag[p]);
53     f(rs(p), mid + 1, r, tag[p]);
54     tag[p] = 0;
55 }
56
57 ll query(ll q_x, ll q_y, ll l, ll r, ll p)
58 {
59     ll res = 922337203685477580;
60     if(q_x <= l && r <= q_y)
61  {
62   return ans[p];
63  }
64     ll mid = (l + r)>>1;
65     push_down(p, l, r);
66     if(q_x <= mid)
67  {
68   res = min(res, query(q_x, q_y, l, mid, ls(p)));
69  }
70     if(q_y > mid)
71  {
72   res = min(res, query(q_x, q_y, mid + 1, r, rs(p)));
73  }
74     return res;
75 }
76
77 int main()
78 {
79      ll e, f;
80     scanf("%lld%lld", &n, &m);
81     for(ll i = 1; i <= n; i++)
82     {
83         scanf("%lld", &a[i]);
84     }
85     build(1, 1, n);
86     for(ll i = 1; i <= m; i++)
87     {
88         scanf("%lld%lld", &e, &f);
89         printf("%lld ", query(e, f, 1, n, 1));
90     }
91     return 0;
92 }
02-13 12:56