其他分享
首页 > 其他分享> > [洛谷P3373] 线段树板子题

[洛谷P3373] 线段树板子题

作者:互联网

线段树区间修改,区间查询模板题
改了n次才过啊!!!
传送门

#include<bits/stdc++.h>
using namespace std;
#define MAX 100005
struct Node
{
    int l,r;
    long long lazyadd,lazymul,val;
}node[MAX<<2];
long long d[MAX],p;
inline void pushup(int rt)
{
    node[rt].val=(node[rt<<1].val+node[rt<<1|1].val)%p;
}
inline void construct(int rt,int l,int r)
{
    node[rt].l=l;
    node[rt].r=r;
    node[rt].lazyadd=node[rt].val=0;
    node[rt].lazymul=1;
    if(l==r)
    {
        node[rt].val=d[l];
        return;
    }
    int mid=(l+r)>>1;
    construct(rt<<1,l,mid);
    construct(rt<<1|1,mid+1,r);
    pushup(rt);
}
inline void pushdown(int rt)
{
    if(node[rt].lazymul!=1)
    {
        node[rt<<1].val=(node[rt<<1].val%p)*(node[rt].lazymul%p)%p;
        node[rt<<1|1].val=(node[rt<<1|1].val%p)*(node[rt].lazymul%p)%p;
        node[rt<<1].lazymul=(node[rt<<1].lazymul%p)*(node[rt].lazymul%p)%p;
        node[rt<<1|1].lazymul=(node[rt<<1|1].lazymul%p)*(node[rt].lazymul%p)%p;
        node[rt<<1].lazyadd=(node[rt<<1].lazyadd)*(node[rt].lazymul)%p;
        node[rt<<1|1].lazyadd=(node[rt<<1|1].lazyadd)*(node[rt].lazymul)%p;
        node[rt].lazymul=1;
    }
    if(node[rt].lazyadd)
    {
        node[rt<<1].val+=(node[rt<<1].r-node[rt<<1].l+1)*node[rt].lazyadd;
        node[rt<<1|1].val+=(node[rt<<1|1].r-node[rt<<1|1].l+1)*node[rt].lazyadd;
        node[rt<<1].lazyadd+=node[rt].lazyadd;
        node[rt<<1|1].lazyadd+=node[rt].lazyadd;
        node[rt].lazyadd=0;
    }
}
inline void modify(int rt,int fr,int to,long long v)
{
    if(fr<=node[rt].l&&to>=node[rt].r)
    {
        node[rt].lazyadd+=v;
        node[rt].val+=v*(node[rt].r-node[rt].l+1);
        return;
    }
    int mid=(node[rt].l+node[rt].r)>>1;
    pushdown(rt);
    if(fr<=mid) modify(rt<<1,fr,to,v);
    if(to>mid)  modify(rt<<1|1,fr,to,v);
    pushup(rt);
}
inline void modify2(int rt,int fr,int to,long long v)
{
    if(fr<=node[rt].l&&to>=node[rt].r)
    {
        node[rt].lazymul=(node[rt].lazymul*v)%p;
        node[rt].lazyadd=(node[rt].lazyadd*v)%p;
        node[rt].val=(v*node[rt].val)%p;
        return;
    }
    int mid=(node[rt].l+node[rt].r)>>1;
    pushdown(rt);
    if(fr<=mid) modify2(rt<<1,fr,to,v);
    if(to>mid)  modify2(rt<<1|1,fr,to,v);
    pushup(rt);
}
inline long long query(int rt,int fr,int to,int l,int r)
{
    if(fr<=l&&to>=r)
        return node[rt].val%p;
    pushdown(rt);
    int mid=(l+r)>>1;
    long long ans=0;
    if(fr<=mid) ans+=query(rt<<1,fr,to,l,mid);
    if(to>mid)  ans+=query(rt<<1|1,fr,to,mid+1,r);
    return ans%p;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("testout.txt","w",stdout);
    long long n,m,a,b,c,k;
    scanf("%lld%lld%lld",&n,&m,&p);
    for(register int i=1;i<=n;++i)
        scanf("%lld",&d[i]),d[i]%=p;
    construct(1,1,n);
    for(register int i=1;i<=m;++i)
    {
        scanf("%lld%lld%lld",&a,&b,&c);
        if(a==2)
        {
            scanf("%lld",&k);
            modify(1,b,c,k%p);
        }
        else if(a==1)
        {
            scanf("%lld",&k);
            modify2(1,b,c,k%p);
        }
        else printf("%lld\n",query(1,b,c,1,n));
    }   
    return 0;
}

更新乘法标记的时候顺便也要把加法标记更新啊!!!

我太菜了

标签:rt,node,洛谷,val,int,线段,long,lazyadd,P3373
来源: https://www.cnblogs.com/123789456ye/p/11025330.html