玄关求条(马蜂良好,有注释)

P3372 【模板】线段树 1

yzjznbQWQ @ 2024-10-23 21:33:21

rt

#include<bits/stdc++.h>
#define ll long long

using namespace std;

const int N = 1e5+5;

inline int read();

int w[N<<1],a[N],lzy_add[N<<1];

inline void pushup(int u) {w[u]=w[u<<1]+w[u<<1|1];} 

inline bool InRange(int L,int R,int l,int r) {return (L>=l)&&(R<=r);}//判断该区间是否是目标区间的子集 

inline bool OutofRange(int L,int R,int l,int r) {return (L>r)||(R<l);}//判断该区间是否和目标区间有交集 

inline void MakeTag_add(int u,int len,int v) {lzy_add[u]+=v;w[u]+=len*v;}//打懒标记 

inline void pushdown(int u,int l,int r)//下放标记 
{
    int mid=(l+r)>>1;
    MakeTag_add(u<<1,mid-l+1,lzy_add[u]);
    MakeTag_add(u<<1|1,r-mid,lzy_add[u]);
    lzy_add[u]=0;
}

inline void build(int u,int l,int r)//建树 
{
    if(l==r)
    {
        w[u]=a[l];
        return;
    }

    int mid=(l+r)>>1; 
    build(u<<1,l,mid);
    build(u<<1|1,mid+1,r);

    pushup(u);
}

inline int query_one(int u,int L,int R,int p)//单点查询(与这题无关 
{
    if(L==R) return w[u];

    int mid=(L+R)>>1;
    if(mid>=p) query_one(u<<1,L,mid,p);
    else query_one(u<<1|1,mid+1,R,p);
}

inline int update_one(int u,int L,int R,int p,int v)//单点修改(与这题无关 
{
    if(L==R) w[u]=v;
    else
    {
        int mid=(L+R)>>1;
        if(mid>=p) update_one(u<<1,L,mid,p,v);
        else update_one(u<<1|1,mid+1,R,p,v);

        pushup(u);
    }
}

inline int query(int u,int L,int R,int l,int r)//区间求和 
{
    if(InRange(L,R,l,r)) return w[u];

    else if(!OutofRange(L,R,l,r))
    {
        int mid=(L+R)>>1;
        pushdown(u,L,R);
        return query(u<<1,L,mid,l,r)+query(u<<1|1,mid+1,R,l,r);
    }

    else return 0;
}

inline void update_add(int u,int L,int R,int l,int r,int v)//区间加 
{
    if(InRange(L,R,l,r)) MakeTag_add(u,R-L+1,v);
    else if(!OutofRange(L,R,l,r))
    {
        int mid=(L+R)>>1;

        pushdown(u,L,R);

        update_add(u<<1,L,mid,l,r,v);
        update_add(u<<1|1,mid+1,R,l,r,v);

        pushup(u);
    }
}

int main(){
    int n=read(),q=read();//mod=read();
    for(int i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    while(q--)
    {
        int opt=read();
        if(opt==1) update_add(1,1,n,read(),read(),read());
        else if(opt==2) printf("%d\n",query(1,1,n,read(),read()));
    }
    return 0;
}

inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-') f=0;
        c=getchar();
    }
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48,c=getchar();
    return f?x:(~(x-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
*/

by ZZ_WYZ @ 2024-10-24 18:48:05

#include<bits/stdc++.h>
#define ll long long
#define int long long

using namespace std;

const int N = 4e5+5;

inline int read();

int w[N<<1],a[N],lzy_add[N<<1];

inline void pushup(int u) {w[u]=w[u<<1]+w[u<<1|1];} 

inline bool InRange(int L,int R,int l,int r) {return (L>=l)&&(R<=r);}//判断该区间是否是目标区间的子集 

inline bool OutofRange(int L,int R,int l,int r) {return (L>r)||(R<l);}//判断该区间是否和目标区间有交集 

inline void MakeTag_add(int u,int len,int v) {lzy_add[u]+=v;w[u]+=len*v;}//打懒标记 

inline void pushdown(int u,int l,int r)//下放标记 
{
    int mid=(l+r)>>1;
    MakeTag_add(u<<1,mid-l+1,lzy_add[u]);
    MakeTag_add(u<<1|1,r-mid,lzy_add[u]);
    lzy_add[u]=0;
}

inline void build(int u,int l,int r)//建树 
{
    if(l==r)
    {
        w[u]=a[l];
        return;
    }

    int mid=(l+r)>>1; 
    build(u<<1,l,mid);
    build(u<<1|1,mid+1,r);
    pushup(u);
}

inline int query_one(int u,int L,int R,int p)//单点查询(与这题无关 
{
    if(L==R) return w[u];

    int mid=(L+R)>>1;
    if(mid>=p) query_one(u<<1,L,mid,p);
    else query_one(u<<1|1,mid+1,R,p);
}

inline int update_one(int u,int L,int R,int p,int v)//单点修改(与这题无关 
{
    if(L==R) w[u]=v;
    else
    {
        int mid=(L+R)>>1;
        if(mid>=p) update_one(u<<1,L,mid,p,v);
        else update_one(u<<1|1,mid+1,R,p,v);

        pushup(u);
    }
}

inline int query(int u,int L,int R,int l,int r)//区间求和 
{

    if(InRange(L,R,l,r)) return w[u];

    else if(OutofRange(L,R,l,r)) return 0;
    else {
        int mid=(L+R)>>1;
        pushdown(u,L,R);
        return query(u<<1,L,mid,l,r)+query(u<<1|1,mid+1,R,l,r);
    }
}

inline void update_add(int u,int L,int R,int l,int r,int v)//区间加 
{
    if(InRange(L,R,l,r)) MakeTag_add(u,R-L+1,v);
    else if(!OutofRange(L,R,l,r))
    {
        int mid=(L+R)>>1;

        pushdown(u,L,R);

        update_add(u<<1,L,mid,l,r,v);
        update_add(u<<1|1,mid+1,R,l,r,v);

        pushup(u);
    }
}

signed main(){
    int n=read(),q=read();//mod=read();
    for(int i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    while(q--)
    {
        int opt=read();
        int a,b,c,d;
        if(opt==1){
            a=read();
            b=read();
            c=read();
            update_add(1,1,n,a,b,c);
        } 
        if(opt==2) {
            a=read();
            b=read();
            printf("%lld\n",query(1,1,n,a,b));
        }
    }
    return 0;
}

inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-') f=0;
        c=getchar();
    }
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48,c=getchar();
    return f?x:(~(x-1));
}

by yzjznbQWQ @ 2024-10-27 16:30:31

@ZZ_WYZ read的问题,服了


by ZZ_WYZ @ 2024-10-27 16:44:08

@yzjznbQWQ 。。。建议这辈子都别碰快读了


by yzjznbQWQ @ 2024-10-27 16:51:26

@ZZ_WYZ CSP-S 刚用。。。。


|