#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<int, 3> ar;
int mod = 1e9+7;
const int maxv = 4e6 + 5;
// #define endl "\n"
struct node
{
int l,r;
int lazy[2];
int sum[2];
#define l(x) tr[x].l
#define r(x) tr[x].r
#define lazy0(x) tr[x].lazy[0]
#define lazy1(x) tr[x].lazy[1]
#define sum0(x) tr[x].sum[0]
#define sum1(x) tr[x].sum[1]
}tr[N];
int a[N];
void update(int p)
{
sum0(p)=sum0(p*2)+sum0(p*2+1);
sum1(p)=sum1(p*2)+sum1(p*2+1);
}
void init_lazy(int p)
{
lazy0(p)=1,lazy1(p)=0;
}
void build(int p,int l,int r)
{
init_lazy(p);
l(p)=l,r(p)=r;
if(l==r){
l(p)=r(p)=l;
sum0(p)=a[l];
sum1(p)=a[l]*a[l];
return ;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
update(p);
}
void union_lazy(int p,int a,int b)
{
lazy0(p)*=a;
lazy1(p)=lazy1(p)*a+b;
}
void cal_lazy(int p,int a,int b)
{
sum1(p)=a*a*sum1(p)+2*a*b*sum0(p)*(r(p)-l(p)+1)*b*b;
sum0(p)=a*sum0(p)+(r(p)-l(p)+1)*b;
}
void pushdown(int p)
{
int a=1,b=0;
if(lazy0(p)!=1||lazy1(p)!=0){
a=lazy0(p);
b=lazy1(p);
cal_lazy(p*2,a,b),cal_lazy(p*2+1,a,b);
union_lazy(p*2,a,b),union_lazy(p*2+1,a,b);
init_lazy(p);
}
}
void modify(int p,int l,int r,int op,int val)
{
if(l<=l(p)&&r(p)<=r){
if(op==0) union_lazy(p,val,0),cal_lazy(p,val,0);
else union_lazy(p,1,val),cal_lazy(p,1,val);
return;
}
pushdown(p);
int mid=(l(p)+r(p))/2;
if(l<=mid) modify(p*2,l,r,op,val);
if(r>mid) modify(p*2+1,l,r,op,val);
update(p);
}
ll query(int p,int l,int r,int op)
{
if(l<=l(p)&&r(p)<=r){
return tr[p].sum[op];
}
pushdown(p);
ll res=0;
int mid=(l(p)+r(p))/2;
if(l<=mid) res+=query(p*2,l,r,op);
if(r>mid) res+=query(p*2+1,l,r,op);
return res;
}
void solve()
{
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(q--){
int op;
cin>>op;
if(op==1){
int l,r;
cin>>l>>r;
cout<<query(1,l,r,1)<<endl;
}
else if(op==2){
int l,r;
cin>>l>>r;
cout<<query(1,l,r,0)<<endl;
}
else if(op==3){
int l,r,x;
cin>>l>>r>>x;
modify(1,l,r,0,x);
}
else {
int l,r,x;
cin>>l>>r>>x;
modify(1,l,r,0,x);
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
t=1;
// cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
线段树加乘维护区间和,区间平方和
最新推荐文章于 2024-10-06 14:10:45 发布