• 洛谷 P1816 忠诚题解


    题目描述

    老管家是一个聪明能干的人。他为财主工作了整整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 }
  • 相关阅读:
    Android 禁用以及捕捉home键
    android中正确导入第三方jar包
    使用SharedPreferences进行数据存储
    tomcat不安全因素
    spring边边角角
    宏定义
    C++变量对比java变量所占内存
    结构指针的分析
    对结构使用指针
    什么是程序文件?
  • 原文地址:https://www.cnblogs.com/zealsoft/p/11559835.html
Copyright © 2020-2023  润新知