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
    */
  • 相关阅读:
    周末之个人杂想(十三)
    PowerTip of the DaySorting Multiple Properties
    PowerTip of the DayCreate Remoting Solutions
    PowerTip of the DayAdd Help to Your Functions
    PowerTip of the DayAcessing Function Parameters by Type
    PowerTip of the DayReplace Text in Files
    PowerTip of the DayAdding Extra Information
    PowerTip of the DayPrinting Results
    Win7下IIS 7.5配置SSAS(2008)远程访问
    PowerTip of the DayOpening Current Folder in Explorer
  • 原文地址:https://www.cnblogs.com/mohari/p/12901479.html
Copyright © 2011-2022 走看看