• 蓝桥杯 算法训练 操作格子 [ 线段树 ]


    传送门

     算法训练 操作格子  

    时间限制:1.0s   内存限制:256.0MB
       
    问题描述

    有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。

    532401 609738062@qq.com 操作格子 04-10 10:34 1.614KB C++ 正确 100 312ms 4.269MB 评测详情
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <cstring>
      6 #include <vector>
      7 #include <queue>
      8 using namespace std;
      9 
     10 #define ll long long
     11 
     12 const int N = 100005;
     13 const ll inf = 0x3f3f3f3f;
     14 
     15 int n,m;
     16 int a[N];
     17 int sum[N*4],ma[N*4];
     18 
     19 void build(int i,int l,int r)
     20 {
     21     if(l==r){
     22         sum[i]=ma[i]=a[l];
     23         return;
     24     }
     25     int mid=(l+r)/2;
     26     build(i*2,l,mid);
     27     build(i*2+1,mid+1,r);
     28     ma[i]=max(ma[i*2],ma[i*2+1]);
     29     sum[i]=sum[i*2]+sum[i*2+1];
     30     return;
     31 }
     32 
     33 void setValue(int i,int l,int r,int x,int y)
     34 {
     35     if(l==r){
     36         ma[i]=sum[i]=a[x]=y;
     37         return;
     38     }
     39     int mid=(l+r)/2;
     40     if(x<=mid)
     41         setValue(i*2,l,mid,x,y);
     42     else
     43         setValue(i*2+1,mid+1,r,x,y);
     44     ma[i]=max(ma[i*2],ma[i*2+1]);
     45     sum[i]=sum[i*2]+sum[i*2+1];
     46 }
     47 
     48 int querysum(int i,int l,int r,int x,int y)
     49 {
     50     if(x>r || y<l){
     51         return 0;
     52     }
     53     else if(x<=l && r<=y){
     54         return sum[i];
     55     }
     56     int mid=(l+r)/2;
     57     int lsum=0,rsum=0;
     58     if(mid>=x){
     59         lsum=querysum(i*2,l,mid,x,y);
     60     }
     61     if(mid<y){
     62         rsum=querysum(i*2+1,mid+1,r,x,y);
     63     }
     64     return lsum+rsum;
     65 }
     66 
     67 int queryma(int i,int l,int r,int x,int y)
     68 {
     69     if(x>r || y<l){
     70         return 0;
     71     }
     72     else if(x<=l && r<=y){
     73         return ma[i];
     74     }
     75     int mid=(l+r)/2;
     76     int lma=0,rma=0;
     77     if(mid>=x){
     78         lma=queryma(i*2,l,mid,x,y);
     79     }
     80     if(mid<y){
     81         rma=queryma(i*2+1,mid+1,r,x,y);
     82     }
     83     return max(lma,rma);
     84 }
     85 
     86 int main()
     87 {
     88     int i;
     89     int p,x,y;
     90     //freopen("data.in","r",stdin);
     91     scanf("%d%d",&n,&m);
     92     for(i=1;i<=n;i++){
     93         scanf("%d",&a[i]);        
     94     }
     95     build(1,1,n);
     96     for(i=1;i<=m;i++){
     97         scanf("%d%d%d",&p,&x,&y);
     98         if(p==1){
     99             setValue(1,1,n,x,y);
    100         }
    101         else if(p==2){
    102             printf("%d
    ",querysum(1,1,n,x,y));
    103         }
    104         else{
    105             printf("%d
    ",queryma(1,1,n,x,y));
    106         }
    107     }
    108     
    109     return 0;
    110 }
  • 相关阅读:
    MySQL 练习题
    MySQL 增删查改
    HTML显示与隐藏
    360布局
    div布局
    HTML练习2
    HTML练习

    if语句的用法及其案例
    输入输出,数据类型与运算符
  • 原文地址:https://www.cnblogs.com/njczy2010/p/4413887.html
Copyright © 2020-2023  润新知