P3372 模板线段树 1

Posted mohari

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
*/

 

以上是关于P3372 模板线段树 1的主要内容,如果未能解决你的问题,请参考以下文章

P3372 模板线段树 1

P3372 模板线段树 1(区间修改区间查询)(树状数组)

P3372 模板线段树 1

线段树模板1 [Luogu P3372]

洛谷P3372 模板线段树 1

P3372 模板线段树 1