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

    资源限制
    时间限制: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 }
  • 相关阅读:
    【矩阵乘】【DP】【codevs 1305】Freda的道路
    Giraph源代码分析(九)—— Aggregators 原理解析
    Dubbo框架应用之(三)--Zookeeper注冊中心、管理控制台的安装及解说
    Oracle中对数字加汉字的排序(完好)
    PKU-2104-K-th Number
    IE下推断IE版本号的语句
    自己定义View时,用到Paint Canvas的一些温故,简单的帧动画(动画一 ,&quot;掏粪男孩Gif&quot;顺便再提提onWindowFocusChanged)
    <html>
    测试一个网段主机在线情况,禁ping的情况除外
    glance image-create --name "wj_js_company_img" --file a0e1c7fa-d6d3-410f-9bb5-e699e342db91 --disk-format qcow2 --container-format bare --progress --visibility public
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/13533954.html
Copyright © 2011-2022 走看看