定义
//定义
struct node {
int l,r;//区间左右端点
long long data;//数据域
long long add,mul;//延迟更新标记
};
node t[400010];
int n,m,mod;
int a[100010];
构造
//构造线段树
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
t[p].mul=1;
if(l==r){
t[p].data=a[l];
return ;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].data=(t[p*2].data+t[p*2+1].data)%mod;
}
小功能
long long get_data(int p){
return (t[p].data+t[p].add*(t[p].r-t[p].l+1))%mod;
}
计算累积
void pushdown(int p){
if(t[p].l<t[p].r){
t[p*2].data=(t[p].mul*t[p*2].data)%mod;
t[p*2+1].data=(t[p].mul*t[p*2+1].data)%mod;
t[p*2].mul=(t[p].mul*t[p*2].mul)%mod;
t[p*2+1].mul=(t[p].mul*t[p*2+1].mul)%mod;
t[p*2].add=(t[p].mul*t[p*2].add+t[p].add)%mod;
t[p*2+1].add=(t[p].mul*t[p*2+1].add+t[p].add)%mod;
}
t[p].data=get_data(p);
t[p].add=0;
t[p].mul=1;
}
乘法
//区间修改(乘法)
void update_mul(int p,int l,int r,int k){
if(l==t[p].l&&r==t[p].r){
t[p].data=(t[p].data*k)%mod;
t[p].add=(t[p].add*k)%mod;
t[p].mul=(t[p].mul*k)%mod;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
update_mul(p*2,l,r,k);
}
else if(l>=mid+1){
update_mul(p*2+1,l,r,k);
}
else{
update_mul(p*2,l,mid,k);
update_mul(p*2+1,mid+1,r,k);
}
t[p].data=(get_data(p*2)+get_data(p*2+1))%mod;
}
加法
//区间修改(加法)
void update_add(int p,int l,int r,int k){
if(l==t[p].l&&r==t[p].r){
t[p].add=(t[p].add+k)%mod;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
update_add(p*2,l,r,k);
}
else if(l>=mid+1){
update_add(p*2+1,l,r,k);
}
else{
update_add(p*2,l,mid,k);
update_add(p*2+1,mid+1,r,k);
}
t[p].data=(get_data(p*2)+get_data(p*2+1))%mod;
return;
}
区间查询
#include <bits/stdc++.h>
using namespace std;
//定义
struct node {
int l,r;//区间左右端点
long long data;//数据域
long long add,mul;//延迟更新标记
};
node t[400010];
int n,m,mod;
int a[100010];
//构造线段树
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
t[p].mul=1;
if(l==r){
t[p].data=a[l];
return ;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].data=(t[p*2].data+t[p*2+1].data)%mod;
}
long long get_data(int p){
return (t[p].data+t[p].add*(t[p].r-t[p].l+1))%mod;
}
void pushdown(int p){
if(t[p].l<t[p].r){
t[p*2].data=(t[p].mul*t[p*2].data)%mod;
t[p*2+1].data=(t[p].mul*t[p*2+1].data)%mod;
t[p*2].mul=(t[p].mul*t[p*2].mul)%mod;
t[p*2+1].mul=(t[p].mul*t[p*2+1].mul)%mod;
t[p*2].add=(t[p].mul*t[p*2].add+t[p].add)%mod;
t[p*2+1].add=(t[p].mul*t[p*2+1].add+t[p].add)%mod;
}
t[p].data=get_data(p);
t[p].add=0;
t[p].mul=1;
}
//区间修改(加法)
void update_add(int p,int l,int r,int k){
if(l==t[p].l&&r==t[p].r){
t[p].add=(t[p].add+k)%mod;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
update_add(p*2,l,r,k);
}
else if(l>=mid+1){
update_add(p*2+1,l,r,k);
}
else{
update_add(p*2,l,mid,k);
update_add(p*2+1,mid+1,r,k);
}
t[p].data=(get_data(p*2)+get_data(p*2+1))%mod;
return;
}
//区间修改(乘法)
void update_mul(int p,int l,int r,int k){
if(l==t[p].l&&r==t[p].r){
t[p].data=(t[p].data*k)%mod;
t[p].add=(t[p].add*k)%mod;
t[p].mul=(t[p].mul*k)%mod;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
update_mul(p*2,l,r,k);
}
else if(l>=mid+1){
update_mul(p*2+1,l,r,k);
}
else{
update_mul(p*2,l,mid,k);
update_mul(p*2+1,mid+1,r,k);
}
t[p].data=(get_data(p*2)+get_data(p*2+1))%mod;
}
//区间查询
long long query(int p,int l,int r){
if(l==t[p].l&&r==t[p].r){
return get_data(p);
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
return query(p*2,l,r)%mod;
}
else if(l>=mid+1){
return query(p*2+1,l,r)%mod;
}
else{
return (query(p*2,l,mid)+query(p*2+1,mid+1,r))%mod;
}
}
int main(){
int opt,x,y,k;
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>opt>>x>>y;
if(opt==1){
cin>>k;
update_mul(1,x,y,k);
}
else if(opt==2){
cin>>k;
update_add(1,x,y,k);
}
else{
cout<<query(1,x,y)<<endl;
}
}
return 0;
}
CODE:
#include <bits/stdc++.h>
using namespace std;
//定义
struct node {
int l,r;//区间左右端点
long long data;//数据域
long long add,mul;//延迟更新标记
};
node t[400010];
int n,m,mod;
int a[100010];
//构造线段树
void build(int p,int l,int r){
t[p].l=l;
t[p].r=r;
t[p].mul=1;
if(l==r){
t[p].data=a[l];
return ;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].data=(t[p*2].data+t[p*2+1].data)%mod;
}
long long get_data(int p){
return (t[p].data+t[p].add*(t[p].r-t[p].l+1))%mod;
}
void pushdown(int p){
if(t[p].l<t[p].r){
t[p*2].data=(t[p].mul*t[p*2].data)%mod;
t[p*2+1].data=(t[p].mul*t[p*2+1].data)%mod;
t[p*2].mul=(t[p].mul*t[p*2].mul)%mod;
t[p*2+1].mul=(t[p].mul*t[p*2+1].mul)%mod;
t[p*2].add=(t[p].mul*t[p*2].add+t[p].add)%mod;
t[p*2+1].add=(t[p].mul*t[p*2+1].add+t[p].add)%mod;
}
t[p].data=get_data(p);
t[p].add=0;
t[p].mul=1;
}
//区间修改(加法)
void update_add(int p,int l,int r,int k){
if(l==t[p].l&&r==t[p].r){
t[p].add=(t[p].add+k)%mod;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
update_add(p*2,l,r,k);
}
else if(l>=mid+1){
update_add(p*2+1,l,r,k);
}
else{
update_add(p*2,l,mid,k);
update_add(p*2+1,mid+1,r,k);
}
t[p].data=(get_data(p*2)+get_data(p*2+1))%mod;
return;
}
//区间修改(乘法)
void update_mul(int p,int l,int r,int k){
if(l==t[p].l&&r==t[p].r){
t[p].data=(t[p].data*k)%mod;
t[p].add=(t[p].add*k)%mod;
t[p].mul=(t[p].mul*k)%mod;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
update_mul(p*2,l,r,k);
}
else if(l>=mid+1){
update_mul(p*2+1,l,r,k);
}
else{
update_mul(p*2,l,mid,k);
update_mul(p*2+1,mid+1,r,k);
}
t[p].data=(get_data(p*2)+get_data(p*2+1))%mod;
}
//区间查询
long long query(int p,int l,int r){
if(l==t[p].l&&r==t[p].r){
return get_data(p);
}
pushdown(p);
int mid=(t[p].l+t[p].r)/2;
if(r<=mid){
return query(p*2,l,r)%mod;
}
else if(l>=mid+1){
return query(p*2+1,l,r)%mod;
}
else{
return (query(p*2,l,mid)+query(p*2+1,mid+1,r))%mod;
}
}
int main(){
int opt,x,y,k;
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>opt>>x>>y;
if(opt==1){
cin>>k;
update_mul(1,x,y,k);
}
else if(opt==2){
cin>>k;
update_add(1,x,y,k);
}
else{
cout<<query(1,x,y)<<endl;
}
}
return 0;
}