P3373 【模板】线段树 2
提交
63.01k
通过
19.89k
时间限制
1.00s
内存限制
125.00MB
提交答案
加入收藏
题目提供者
HansBug
难度
普及+/提高
历史分数
100
提交记录 查看题解
标签
高性能
进入讨论版
相关讨论
推荐题目
展开
题目描述
如题,已知一个数列,你需要进行下面三种操作:
将某区间每一个数乘上 xx
将某区间每一个数加上 xx
求出某区间每一个数的和
输入格式
第一行包含三个整数 n,m,pn,m,p,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含 nn 个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。
接下来 mm 行每行包含若干个整数,表示一个操作,具体如下:
操作 11: 格式:1 x y k 含义:将区间 [x,y][x,y] 内每个数乘上 kk
操作 22: 格式:2 x y k 含义:将区间 [x,y][x,y] 内每个数加上 kk
操作 33: 格式:3 x y 含义:输出区间 [x,y][x,y] 内每个数的和对 pp 取模所得的结果
输出格式
输出包含若干行整数,即为所有操作 33 的结果。
输入输出样例
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=100005;
ll a[maxn<<2],addtag[maxn],multag[maxn],aa[maxn];
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
ll mod,n,m;
void build(ll rt,ll l,ll r){
addtag[rt]=0;
multag[rt]=1;
if(l==r){
a[rt]=aa[l]%mod;
return ;
}
ll mid=(l+r)>>1;
build(lson);
build(rson);
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
void move(ll rt,ll l,ll r,ll mt,ll at){
a[rt]=(mt*a[rt]+(r-l+1)*at)%mod;
multag[rt]=(multag[rt]*mt)%mod;
addtag[rt]=(addtag[rt]*mt+at)%mod;
}
void pushdown(ll rt,ll l,ll r){
ll mid=(l+r)>>1;
move(lson,multag[rt],addtag[rt]);
move(rson,multag[rt],addtag[rt]);
addtag[rt]=0;
multag[rt]=1;
}
void mutupdate(ll ql,ll qr,ll rt,ll l ,ll r,ll k){
if(ql<=l&&r<=qr){
a[rt]=(a[rt]*k)%mod;
multag[rt]=(multag[rt]*k)%mod;
addtag[rt]=(addtag[rt]*k)%mod;
return ;
}
pushdown(rt,l,r);
ll mid=(l+r)>>1;
if(ql<=mid){
mutupdate(ql,qr,lson,k);
}
if(mid<qr){
mutupdate(ql,qr,rson,k);
}
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
void addupdate(ll ql,ll qr,ll rt,ll l ,ll r,ll k){
if(ql<=l&&r<=qr){
a[rt]=(a[rt]+(r-l+1)*k)%mod;
addtag[rt]=(addtag[rt]+k)%mod;
return ;
}
pushdown(rt,l,r);
ll mid=(l+r)>>1;
if(ql<=mid){
addupdate(ql,qr,lson,k);
}
if(mid<qr){
addupdate(ql,qr,rson,k);
}
a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}
ll query(ll ql,ll qr,ll rt,ll l,ll r){
if(ql<=l&&r<=qr){
return a[rt]%mod;
}
pushdown(rt,l,r);
ll mid=(l+r)>>1;
ll ans=0;
if(ql<=mid){
ans=(ans+query(ql,qr,lson))%mod;
}
if(mid<qr){
ans=(ans+query(ql,qr,rson))%mod;
}
return ans%mod;
}
int main(){
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>aa[i];
}
build(1,1,n);
while(m--){
ll x,y,z,w;
cin>>x;
if(x==1){
cin>>y>>z>>w;
mutupdate(y,z,1,1,n,w%mod);
}
if(x==2){
cin>>y>>z>>w;
addupdate(y,z,1,1,n,w%mod);
}
if(x==3){
cin>>y>>z;
cout<<query(y,z,1,1,n)<<endl;
}
}
return 0;
}