维护区间和的只有加法操作线段树模板
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
#define maxn 100001
using namespace std;
struct Tree{
int l,r;
ll sum;
int add;
}t[maxn*4];
ll a[maxn];
int n,m;
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(t[p].l==t[p].r)
{
t[p].sum=a[l];
return ;
}
int mid=(t[p].l+t[p].r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void spread(int p)
{
if(!t[p].add) return;
t[p*2].sum+=(t[p*2].r-t[p*2].l+1)*t[p].add,t[p*2].add+=t[p].add;
t[p*2+1].sum+=(t[p*2+1].r-t[p*2+1].l+1)*t[p].add,t[p*2+1].add+=t[p].add;
t[p].add=0;
}
void change(int p,int l,int r,int k)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].sum+=(t[p].r-t[p].l+1)*k;
t[p].add+=k;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
spread(p);
if(l<=mid) change(p*2,l,r,k);
if(r>mid) change(p*2+1,l,r,k);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
ll ask(int p,int l,int r)
{
if(t[p].l>=l&&t[p].r<=r) return t[p].sum;
int mid=(t[p].l+t[p].r)>>1;
spread(p);
ll val=0;
if(l<=mid) val+=ask(p*2,l,r);
if(r>mid) val+=ask(p*2+1,l,r);
return val;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(int i=1;i<=m;i++)
{
int d;
scanf("%d",&d);
if(d==1)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
change(1,x,y,k);
}
if(d==2)
{
int x,y;
scanf("%d%d",&x,&y);
ll ans=ask(1,x,y);
printf("%lld\n",ans);
}
}
}
维护区间和的既有加法又有乘法的线段树模板
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
#define maxn 100005
using namespace std;
struct Tree{
int l,r;
ll add1,add2;
ll sum;
}t[maxn*4];
int kk;
ll a[maxn];
int n,m;
ll mod;
void build(int p,int l,int r)
{
t[p].add1=1;
t[p].l=l,t[p].r=r;
if(t[p].l==t[p].r)
{
t[p].sum=a[l]%mod;
return;
}
int mid=(t[p].l+t[p].r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
void spread(int p)
{
t[p*2].sum=((t[p*2].sum*t[p].add1)%mod+(t[p*2].r-t[p*2].l+1)*t[p].add2%mod)%mod;
t[p*2+1].sum=((t[p*2+1].sum*t[p].add1)%mod+(t[p*2+1].r-t[p*2+1].l+1)*t[p].add2%mod)%mod;
t[p*2].add1=(t[p*2].add1*t[p].add1)%mod;
t[p*2].add2=(t[p*2].add2*t[p].add1+t[p].add2)%mod;
t[p*2+1].add1=(t[p*2+1].add1*t[p].add1)%mod;
t[p*2+1].add2=(t[p*2+1].add2*t[p].add1+t[p].add2)%mod;
t[p].add1=1;
t[p].add2=0;
}
void change1(int p,int l,int r,int k)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].sum=(t[p].sum*k)%mod;
t[p].add2=(t[p].add2*k)%mod;
t[p].add1=(t[p].add1*k)%mod;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change1(p*2,l,r,k);
if(r>mid) change1(p*2+1,l,r,k);
t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
void change2(int p,int l,int r,int k)
{
if(t[p].l>=l&&t[p].r<=r)
{
t[p].sum=(t[p].sum+(t[p].r-t[p].l+1)*k)%mod;
t[p].add2=(t[p].add2+k)%mod;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change2(p*2,l,r,k);
if(r>mid) change2(p*2+1,l,r,k);
t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
ll ask(int p,int l,int r)
{
if(t[p].l>=l&&t[p].r<=r) return t[p].sum;
int mid=(t[p].l+t[p].r)>>1;
spread(p);
ll val=0;
if(l<=mid) val=(val+ask(p*2,l,r))%mod;
if(r>mid) val=(ask(p*2+1,l,r)+val)%mod;
return val;
}
int main()
{
//freopen("xds.in","r",stdin);
//freopen("xds.out","w",stdout);
scanf("%d%d%lld",&n,&m,&mod);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(int i=1;i<=m;i++)
{
int d;
scanf("%d",&d);
if(d==1)
{
int x,y;
ll k;
scanf("%d%d%lld",&x,&y,&k);
change1(1,x,y,k%mod);
}
if(d==2)
{
int x,y;
ll k;
scanf("%d%d%lld",&x,&y,&k);
change2(1,x,y,k%mod);
}
if(d==3)
{
kk++;
int x,y;
scanf("%d%d",&x,&y);
ll ans=ask(1,x,y);
printf("%d.%lld\n",kk,ans%mod);
}
}
return 0;
}