zoukankan      html  css  js  c++  java
  • 算法训练 操作格子

    问题描述

    有n个格子,从左到右放成一排,编号为1-n。

    共有m次操作,有3种操作类型:

    1.修改一个格子的权值,

    2.求连续一段格子权值和,

    3.求连续一段格子的最大值。

    对于每个2、3操作输出你所求出的结果。

    输入格式

    第一行2个整数n,m。

    接下来一行n个整数表示n个格子的初始权值。

    接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。

    输出格式

    有若干行,行数等于p=2或3的操作总数。

    每行1个整数,对应了每个p=2或3操作的结果。

    样例输入
    4 3
    1 2 3 4
    2 1 3
    1 4 3
    3 1 4
    样例输出
    6
    3
    数据规模与约定

    对于20%的数据n <= 100,m <= 200。

    对于50%的数据n <= 5000,m <= 5000。

    对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。

     
    练习了一下线段树,习惯了敲模板,蓝桥杯却不能看模板,赶脚好痛苦。。。
    #include <cstdio>
    #include <algorithm>
    #define N 1000005
    #define ll long long
    using namespace std;
    ll sum[N] = {0};
    ll Max[N] = {0};
    void PushUp(int rt)
    {
        Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    
    void Build(int rt, int l, int r)
    {
        if(l == r) {
                scanf("%I64d", &sum[rt]);
                Max[rt] = sum[rt];
        }
        else {
            int m = (l + r) >> 1;
            Build(rt << 1, l, m);
            Build(rt << 1 | 1, m + 1, r);
            PushUp(rt);
        }
    }
    
    void UpDate(int p, int val, int l, int r, int rt)
    {
        if(l == r) { sum[rt] = val; Max[rt] = val; }
        else {
            int m = (l + r) >> 1;
            if(p <= m) UpDate(p, val, l, m, rt << 1);
            else       UpDate(p, val, m + 1, r, rt << 1 | 1);
            PushUp(rt);
        }
    }
    
    ll Query_max(int L, int R, int l, int r, int rt)
    {
        if(L <= l && R >= r) return Max[rt];
        else {
            int m = (l + r) >> 1;
            ll ans = 0;
            if(L <= m) ans = max(Query_max(L, R, l, m, rt << 1), ans);
            if(R > m)  ans = max(Query_max(L, R, m + 1 , r, rt << 1 | 1), ans);
            return ans;
        }
    }
    
    ll Query_sum(int L, int R, int l, int r, int rt)
    {
        if(L <= l && R >= r) return sum[rt];
        else {
            int m = (l + r) >> 1;
            ll ans = 0;
            if(L <= m) ans += Query_sum(L, R, l, m, rt << 1);
            if(m < R)  ans += Query_sum(L, R, m + 1 , r, rt << 1 | 1);
            return ans;
        }
    }
    
    int main()
    {
        int n, q;
        scanf("%d%d", &n, &q);
        Build(1, 1, n);
        for(int i = 0; i < q; i++)
        {
            int op, a, b;
            scanf("%d%d%d", &op, &a, &b);
            if(op == 1) UpDate(a, b, 1, n, 1);
            else if(op == 2) printf("%I64d
    ", Query_sum(a, b, 1, n, 1));
            else             printf("%I64d
    ", Query_max(a, b, 1, n, 1));
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    etcd基本操作
    使用docker配置etcd集群
    etcd启用https服务
    etcd3集群管理
    Opengl绘制我们的小屋(一)球体,立方体绘制
    OpenGL 用三角形模拟生成球面
    PDFSharp生成PDF.
    OpenXml操作Word的一些操作总结.无word组件生成word.
    F# 图形数学基础。
    SQL Server (MSSQLSERVER) 服务因 2148081668 服务性错误而停止。
  • 原文地址:https://www.cnblogs.com/sunus/p/4533565.html
Copyright © 2011-2022 走看看