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

    很好的题解链接,学到了懒标记和线段树的更容易写的版本。https://llkabs.blog.luogu.org/xian-duan-shu

    本题主要解决区间修改,而不是单点修改。

    ac代码如下

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    const int maxn=500005+5;
    struct node{
        ll  l,r,lazy,sum;
    }tree[4*maxn];
    vector<ll>a(maxn);
    void build_tree(int node,int l,int r)
    {
        tree[node].l=l;
        tree[node].r=r;
        if(l==r){
            tree[node].sum=a[l];
            return ;
        }
        int mid=(l+r)>>1;
        int lnode=node*2+1;
        int rnode=node*2+2;
        build_tree(lnode,l,mid);
        build_tree(rnode,mid+1,r);
        tree[node].sum=tree[lnode].sum+tree[rnode].sum;
    }
    void down(int node)
    {
        tree[node*2+1].lazy+=tree[node].lazy;
        tree[node*2+1].sum+=(tree[node*2+1].r-tree[node*2+1].l+1)*tree[node].lazy;
        tree[node*2+2].lazy+=tree[node].lazy;
        tree[node*2+2].sum+=(tree[node*2+2].r-tree[node*2+2].l+1)*tree[node].lazy;
        tree[node].lazy=0;
    }
    void update(int node,int x,int y,int k)
    {
        if(tree[node].l>y||tree[node].r<x)return ;
        if(tree[node].l>=x&&tree[node].r<=y){
            tree[node].lazy+=k;
            tree[node].sum+=(tree[node].r-tree[node].l+1)*k;
            return;
        }
        if(tree[node].lazy>0)down(node);
        update(node*2+1,x,y,k);
        update(node*2+2,x,y,k);
        tree[node].sum=tree[node*2+1].sum+tree[node*2+2].sum;
    }
    ll query(int node,int x,int y)
    {
        if(tree[node].l>y||tree[node].r<x)return 0;
        if(tree[node].l>=x&&tree[node].r<=y){
            return tree[node].sum;
        }
        if(tree[node].lazy>0)down(node);
        return query(2*node+1,x,y)+query(2*node+2,x,y);
    }
    void show(){
        for(int i=0;i<15;i++){
            cout<<"**"<<tree[i].sum<<"**"<<endl;
        }
    }
    int main()
    {
        int n,m,op,x,y,k;scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)scanf("%ld",&a[i]);
        build_tree(0,0,n-1);
        for(int i=0;i<m;i++){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d",&x,&y,&k);
                update(0,x-1,y-1,k);
               /// show();
            }
            else{
                scanf("%d%d",&x,&y);
                cout<<query(0,x-1,y-1)<<endl;
            }
        }
    }
    /*
    8 10
    659 463 793 740 374 330 772 681
    1 5 8 39
    2 5 8
    1 3 6 3
    1 5 8 90
    1 1 5 21
    2 3 8
    1 3 8 17
    1 4 7 52
    2 2 6
    1 2 7 41
    */
  • 相关阅读:
    1648 最大和
    poj2243
    Codevs 2307[SDOI2009]HH的项链
    2597 团伙
    一个JavaWeb项目中使用的部分技术
    Oracle 11g 学习3——表空间操作
    iOS实现抽屉效果
    用shell脚本实现linux系统上wifi模式(STA和soft AP)的转换
    Codeforces Round #243 (Div. 1)——Sereja and Two Sequences
    站点选择配色诀窍
  • 原文地址:https://www.cnblogs.com/mohari/p/12901479.html
Copyright © 2011-2022 走看看