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。

     
     
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    struct node
    {
        int left,right,n,sum;
    }tree[1000000*4];
    void  init(int l,int r,int i)
    {
        tree[i].left = l;
        tree[i].right = r;
        tree[i].n = 0;
        tree[i].sum = 0;
        if(l==r)
            return ;
        else 
        {
            int mid = (l + r) / 2;
            init(l,mid,2*i);
            init(mid+1,r,2*i+1);
        }
    }
    void insert(int i,int x,int m)
    {
        if(x>=tree[i].left && x<=tree[i].right)
        {
            tree[i].n = m;
            tree[i].sum = m;
        }
        if(tree[i].left == tree[i].right)
            return ;
        int mid = (tree[i].left + tree[i].right) / 2;
        if(x>mid)
            insert(2*i+1,x,m);
        else 
            insert(2*i,x,m);
        tree[i].sum = tree[2*i].sum + tree[2*i+1].sum;
        tree[i].n = max(tree[2*i].n ,tree[2*i+1].n);
    }
    
    int findmax(int x,int y,int i)
    {
        if(x==tree[i].left && y==tree[i].right)
            return tree[i].n;
        int mid = (tree[i].left + tree[i].right) / 2;
        if(x>mid)
            return findmax(x,y,2*i+1);
        else if(y<=mid)
            return findmax(x,y,2*i);
        else 
            return max(findmax(x,mid,2*i),findmax(mid+1,y,2*i+1));
    }
    int findsum(int x,int y,int i)
    {
    if(x==tree[i].left && y==tree[i].right)
            return tree[i].sum;
        int mid = (tree[i].left + tree[i].right) / 2;
        if(x > mid)
            return findsum(x,y,2*i+1);
        else  if(y<=mid)
            return findsum(x,y,2*i);
        else 
            return findsum(x,mid,2*i)+findsum(mid+1,y,2*i+1);
    }
    int main()
    {
        int n,m,i,b,x,y,cas;
        cin>>n>>m;
        init(1,n,1);
        for(i=1;i<=n;i++)
        
        {
            cin>>b;
            insert(1,i,b);
        }
        while(m--)
        {
            cin>>cas>>x>>y;
            if(cas==1)
                insert(1,x,y);
            else if(cas==2)
                cout<<findsum(x,y,1)<<endl;
            else if(cas==3)
                cout<<findmax(x,y,1)<<endl;
    
        }
        system("pause");
        return 0;
    }
  • 相关阅读:
    一线架构师实践指南读后感
    可修改性战术
    软件架构师如何工作?
    寒假学习第十五天
    寒假学习第十四天
    寒假学习第十三天
    寒假学习第十二天
    寒假学习第十一天
    寒假学习第十天
    如何变得聪明
  • 原文地址:https://www.cnblogs.com/Deng1185246160/p/3585130.html
Copyright © 2011-2022 走看看