• 试题 算法训练 操作格子


    资源限制
    时间限制: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。

    这题考察了线段树-[单点更新 区间查询]的内容,首先要建个线段树,包含区间左右端点、最大值和权值和.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <algorithm>
     8 #define INF 0x3f3f3f3f
     9 #define zero 1e-7
    10 
    11 using namespace std;
    12 typedef long long ll;
    13 const ll mod=1000000007;
    14 const ll max_n=1e5+5;
    15 
    16 struct tree{
    17     int l, r, sum, maxx;
    18 }t[max_n<<2];
    19 
    20 int a[max_n];
    21 int n, m;
    22 
    23 void build(int i, int l, int r) {//节点,区间左端点、右端点 
    24     t[i].l=l;
    25     t[i].r=r;
    26     if(l==r) {
    27         t[i].maxx=t[i].sum=a[r];
    28         return;
    29     }
    30     int mid=(l+r)>>1;
    31     build(i<<1, l, mid);
    32     build(i<<1|1, mid+1, r);
    33     t[i].sum=t[i<<1].sum+t[i<<1|1].sum;
    34     t[i].maxx=max(t[i<<1].maxx, t[i<<1|1].maxx);
    35 }
    36 
    37 void update(int i, int x, int y) {//节点,要修改的格子编号,新的权值 
    38     if(t[i].l==t[i].r) {//找到要修改的格子 
    39         t[i].sum=t[i].maxx=y;
    40         return;
    41     }
    42     int mid=(t[i].l+t[i].r)>>1;
    43     if(x<=mid) //在该节点的左子节点 
    44         update(i<<1, x, y);
    45     else //在该节点的右子节点
    46         update(i<<1|1, x, y);
    47     t[i].sum=t[i<<1].sum+t[i<<1|1].sum;
    48     t[i].maxx=max(t[i<<1].maxx, t[i<<1|1].maxx);
    49 }
    50 
    51 int getsum(int i, int x, int y) {
    52     if(t[i].l>=x && t[i].r<=y) //该节点所在区间完全被包含在目标区间里面 
    53         return t[i].sum;
    54     int mid=(t[i].l+t[i].r)>>1;
    55     int ans=0;
    56     if(x<=mid) ans+=getsum(i<<1, x, y);
    57     if(y>mid) ans+=getsum(i<<1|1, x, y);
    58     return ans;
    59 }
    60 
    61 int getmax(int i, int x, int y) {
    62     if(t[i].l>=x && t[i].r<=y) 
    63         return t[i].maxx;
    64     int mid=(t[i].l+t[i].r)>>1;
    65     int maxy=-1;
    66     if(x<=mid) maxy=max(maxy, getmax(i<<1, x, y));
    67     if(y>mid) maxy=max(maxy, getmax(i<<1|1, x, y));
    68     return maxy;
    69 }
    70 
    71 int main() {
    72     cin>>n>>m;
    73     for(int i=1; i<=n; i++) {
    74         scanf("%d", &a[i]);
    75     }
    76     build(1, 1, n);//根节点,区间左端点,右端点
    77     int p, x, y;
    78     for(int i=0; i<m; i++) {
    79         scanf("%d %d %d", &p, &x, &y);
    80         switch(p) {
    81             case 1: update(1, x, y); break;
    82             case 2: printf("%d
    ", getsum(1, x, y)); break;
    83             case 3: printf("%d
    ", getmax(1, x, y)); break;
    84             default: break; 
    85         }
    86     } 
    87     return 0;
    88 }
  • 相关阅读:
    页面控制多角度看Model1与Model2
    类型抽象Haxe3新增特性:抽象类型 Abstract Types
    hadoop配置Hadoop 2.0分布式环境搭建安装配置
    PostThreadMessage的应用
    禁用安全模式(2k,2k3,xp)
    如何使用内存池监视器 (Poolmon.exe) 解决内核模式内存泄漏
    WideCharToMultiByte,MultiByteToWideChar
    禁止stMgr.exe
    GetCurrentUserSid
    注册表修改大全
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/13533954.html
Copyright © 2020-2023  润新知