zoukankan      html  css  js  c++  java
  • P3372 【模板】线段树 1

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.求出某区间每一个数的和

    输入格式

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

    输出格式

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入 #1
    5 5
    1 5 4 2 3
    2 2 4
    1 2 3 2
    2 3 4
    1 1 5 1
    2 1 4
    输出 #1
    11
    8
    20

    说明/提示

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^,保证在int64/long long数据范围内)

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int inf=100000;
    void bulid_tree(int arr[],int tree[],int node,int s,int e)
    {
        if(s==e)
        {
            tree[node]=arr[s];
        }
        else{
        int mid=(e+s)/2;
        int left_node=node*2+1;
        int right_node=node*2+2;
        bulid_tree(arr,tree,left_node,s,mid);
        bulid_tree(arr,tree,right_node,mid+1,e);
        tree[node]=tree[left_node]+tree[right_node];
        }
    }
    int quary(int arr[],int tree[],int node,int s,int e,int l,int r)
    {
        if(e<l||r<s)
        return 0;
        else if(l<=s&&e<=r)
        {
            return tree[node];
        }
        else if(s==e)
        {
        return tree[node];
        }
        else{
        int mid=(e+s)/2;
        int left_node=node*2+1;
        int right_node=node*2+2;
        int sum_left=quary(arr,tree,left_node,s,mid,l,r);
        int sum_right=quary(arr,tree,right_node,mid+1,e,l,r);
        return sum_left+sum_right;
       }
    }
    void updata(int arr[],int tree[],int node,int s,int e,int l,int r,int val)
    {
        if(e<l||r<s)
        return ;
        if(s==e)
        {
            tree[node]+=val;
        }
        else
        {
        int mid=(e+s)/2;
        int left_node=node*2+1;
        int right_node=node*2+2;
        updata(arr,tree,left_node,s,mid,l,r,val);
        updata(arr,tree,right_node,mid+1,e,l,r,val);
        tree[node]=tree[left_node]+tree[right_node];
        }
    }
    int main()
    {
        int n,m,arr[inf],tree[4*inf],op,x,y,k;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        cin>>arr[i];
        bulid_tree(arr,tree,0,1,n);
        //for(int i=0;i<4*n;i++)
        //cout<<tree[i]<<" ";
        //cout<<"--------------------"<<endl;
        while(m--)
        {
            cin>>op;
            if(op==1)
            {
                cin>>x>>y>>k;
                updata(arr,tree,0,1,n,x,y,k);
            }
            if(op==2)
            {
                cin>>x>>y;
                cout<<quary(arr,tree,0,1,n,x,y)<<endl;
            }
        }
        return 0;
     } 
    如果你够坚强够勇敢,你就能驾驭他们
  • 相关阅读:
    Java第三次作业第四题
    Java第三次作业第三题
    Java第三次作业第二题
    Java第三次作业第一题
    具有注册、登陆以及后台管理功能的web开发
    KMP算法
    二叉排序树-插入算法
    算法刷题-1-单链表操作
    最牛X的编码套路
    day03 高级模块
  • 原文地址:https://www.cnblogs.com/liuzhaojun/p/11270715.html
Copyright © 2011-2022 走看看