洛谷线段树2模板

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>

#include <cstdio>

#include <fstream>

#include <algorithm>

#include <cmath>

#include <deque>

#include <vector>

#include <queue>

#include <string>

#include <cstring>

#include <map>

#include <stack>

#include <set>

using namespace std;

typedef long long int LL;

const int N=1e5+50;

LL n,m,p;

struct date

{

LL sum;

LL l,r,add,mul;

}tree[4*N];

LL arr[N];

void pushup(LL u)

{

tree[u].sum=(tree[u<<1].sum+tree[u<<1|1].sum)%p;

}

void change(LL u,LL Add,LL Mul)

{

tree[u].sum=(tree[u].sum*Mul%p+((tree[u].r-tree[u].l+1)*Add)%p)%p;

tree[u].mul=tree[u].mul*Mul%p;

tree[u].add=(tree[u].add*Mul%p+Add)%p;

}

void pushdown(LL u)

{

if(tree[u].add!=0||tree[u].mul!=1)

{

change(u<<1,tree[u].add,tree[u].mul);

change(u<<1|1,tree[u].add,tree[u].mul);

tree[u].add=0;

tree[u].mul=1;

}

}

void build(LL x,LL l,LL r)

{

tree[x].l=l;

tree[x].r=r;

tree[x].add=0;

tree[x].mul=1;

if(l==r)

{

tree[x].sum=arr[l];

return;

}

LL mid=l+r>>1;

build(x<<1,l,mid);

build(x<<1|1,mid+1,r);

pushup(x);

}

void modify(LL x,LL l,LL r,LL Add,LL Mul)

{

if(tree[x].l>=l&&tree[x].r<=r)

{

change(x,Add,Mul);

return;

}

LL mid=tree[x].l+tree[x].r>>1;

pushdown(x);

if(mid>=l) modify(x<<1,l,r,Add,Mul);

if(r>mid) modify(x<<1|1,l,r,Add,Mul);

pushup(x);

}

LL query(LL u,LL l,LL r)

{

if(tree[u].l>=l&&tree[u].r<=r)

return tree[u].sum;

LL mid=tree[u].l+tree[u].r>>1;

LL res=0;

pushdown(u);

if(mid>=l) res=(res+query(u<<1,l,r))%p;

if(r>mid) res=(res+query(u<<1|1,l,r))%p;

return res;

}

int main()

{

LL i,j;

cin>>n>>m>>p;

for(i=1;i<=n;i++)

{

cin>>arr[i];

}

build(1,1,n);

for(i=1;i<=m;i++)

{

LL w;

cin>>w;

if(w==1)

{

LL w1,w2,w3;

cin>>w1>>w2>>w3;

modify(1,w1,w2,0,w3);

}

else if(w==2)

{

LL w1,w2,w3;

cin>>w1>>w2>>w3;

modify(1,w1,w2,w3,1);

}

else if(w==3)

{

LL w1,w2;

cin>>w1>>w2;

LL t=query(1,w1,w2);

cout<<t<<'\n';

}

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值