#include<bits/stdc++.h> #define FILE "read" #define MAXN 100010 using namespace std; typedef long long ll; struct node{ll maxx,minn,delta,sum;}tr[MAXN<<3]; char buf[1<<15],*fs,*ft; inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} inline int read(){ int x=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } void relord(int p){ tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum; tr[p].maxx=max(tr[p<<1].maxx,tr[p<<1|1].maxx); tr[p].minn=min(tr[p<<1].minn,tr[p<<1|1].minn); } void pushdown(int p,int l,int r){ int mid=(l+r)>>1; if(tr[p].delta){ ll temp=tr[p].delta; tr[p<<1].delta+=temp; tr[p<<1|1].delta+=temp; tr[p<<1].maxx+=temp; tr[p<<1|1].maxx+=temp; tr[p<<1].minn+=temp; tr[p<<1|1].minn+=temp; tr[p<<1].sum+=temp*(mid-l+1); tr[p<<1|1].sum+=temp*(r-mid); tr[p].delta=0; } } void build(int p,int l,int r){ if(l==r){tr[p].sum=tr[p].maxx=tr[p].minn=read(); return;} int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); relord(p); } void add(int p,int l,int r,int x,int y,int v){ pushdown(p,l,r); if(x<=l&&y>=r){ tr[p].delta+=v; tr[p].maxx+=v; tr[p].minn+=v; tr[p].sum+=(ll)v*(r-l+1); return; } int mid=(l+r)>>1; if(x<=mid) add(p<<1,l,mid,x,y,v); if(y>mid) add(p<<1|1,mid+1,r,x,y,v); relord(p); } void updata(int p,int l,int r,int x,int y){ pushdown(p,l,r); if(x<=l&&y>=r&&tr[p].maxx-tr[p].minn==(ll)sqrt(tr[p].maxx)-(ll)sqrt(tr[p].minn)){ ll v=(ll)sqrt(tr[p].maxx)-tr[p].maxx; tr[p].sum+=v*(r-l+1); tr[p].maxx+=v; tr[p].minn+=v; tr[p].delta+=v; return; } int mid=(l+r)>>1; if(x<=mid) updata(p<<1,l,mid,x,y); if(y>mid) updata(p<<1|1,mid+1,r,x,y); relord(p); } ll query(int p,int l,int r,int x,int y){ pushdown(p,l,r); if(x<=l&&y>=r) return tr[p].sum; int mid=(l+r)>>1; ll ret=0; if(x<=mid) ret+=query(p<<1,l,mid,x,y); if(y>mid) ret+=query(p<<1|1,mid+1,r,x,y); return ret; } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); int n=read(),m=read(); build(1,1,n); for(int i=1;i<=m;++i){ int opt=read(),l=read(),r=read(); if(opt==1){int x=read();add(1,1,n,l,r,x);} else if(opt==2)updata(1,1,n,l,r); else printf("%lld\n",query(1,1,n,l,r)); } return 0; }
|