[洛谷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