#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<algorithm> #define kl (k<<1) #define kr ((k<<1)+1) #define mid ((l+r)>>1) using namespace std; typedef long long lint; const int maxn=1e5 + 10; int T, n, m; struct node { lint mn, mx, sum, tmp; node(lint _mn=0, lint _mx=0, lint s=0, lint t=0) { mn=_mn, mx=_mx, sum=s, tmp=t; } }tr[maxn<<2]; void Get_lint(lint &num, char c=0) { for(c=getchar(); c<'0'||c>'9'; c=getchar()); for(num=c-48; c=getchar(), c>='0'&&c<='9'; num=num*10+c-48); return ; } void Build(int k=1, int l=1, int r=n) { tr[k].mn=tr[k].mx=tr[k].sum=tr[k].tmp=0; if(l==r) return ; Build(kl, l, mid); Build(kr, mid+1, r); return ; } void Push_down(int k, int l, int r) { tr[kl].mn+=tr[k].tmp, tr[kl].mx+=tr[k].tmp, tr[kl].sum+=(mid-l+1)*tr[k].tmp, tr[kl].tmp+=tr[k].tmp; tr[kr].mn+=tr[k].tmp, tr[kr].mx+=tr[k].tmp, tr[kr].sum+=(r-mid)*tr[k].tmp, tr[kr].tmp+=tr[k].tmp; tr[k].tmp=0; return ; } void Push_up(int k, int l, int r) { tr[k].mn=min(tr[kl].mn, tr[kr].mn); tr[k].mx=max(tr[kl].mx, tr[kr].mx); tr[k].sum=tr[kl].sum+tr[kr].sum; return ; } void Insert(int ll, int rr, lint x, int k=1, int l=1, int r=n) { if(rr <l||r< ll) return ; if(ll<=l&&r<=rr) { tr[k].mn+=x, tr[k].mx+=x, tr[k].sum+=(r-l+1)*x, tr[k].tmp+=x; return ; } if(tr[k].tmp) Push_down(k, l, r); Insert(ll, rr, x, kl, l, mid); Insert(ll, rr, x, kr, mid+1, r); Push_up(k, l, r); return ; } void Modify(int ll, int rr, int k=1, int l=1, int r=n) { if(rr <l||r< ll) return ; if(ll<=l&&r<=rr) { if(tr[k].mn==tr[k].mx) { lint tmp=sqrt(tr[k].mn); tr[k].tmp+=tmp-tr[k].mn, tr[k].sum=(r-l+1)*tmp, tr[k].mn=tr[k].mx=tmp; return ; } else if(tr[k].mn+1==tr[k].mx) { lint tp1=sqrt(tr[k].mn), tp2=sqrt(tr[k].mx); if(tp1+1==tp2) { tr[k].tmp+=tp1-tr[k].mn, tr[k].sum+=(r-l+1)*(tp1-tr[k].mn), tr[k].mn=tp1, tr[k].mx=tp2; return ; } } } if(tr[k].tmp) Push_down(k, l, r); Modify(ll, rr, kl, l, mid); Modify(ll, rr, kr, mid+1, r); Push_up(k, l, r); return ; } lint Query(int ll, int rr, int k=1, int l=1, int r=n) { if(rr <l||r< ll) return 0; if(ll<=l&&r<=rr) return tr[k].sum; if(tr[k].tmp) Push_down(k, l, r); return Query(ll, rr, kl, l, mid)+Query(ll, rr, kr, mid+1, r); } int main() { scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); Build(); lint d, l, r, x; for(int i=1; i<=n; i++) { Get_lint(x); Insert(i, i, x); } for(int i=1; i<=m; i++) { Get_lint(d), Get_lint(l), Get_lint(r); if(d==1) { Get_lint(x); Insert(l, r, x); } else if(d==2) Modify(l, r); else printf("%lld\n", Query(l, r)); } } return 0; }
|