1,3,4 are operating normal operation, I do not speak.
Then we consider how to deal with the interval division.
First easy to think of a number \ (the X-\) , which in addition to at least once except \ (2 \) , then it is up to other than \ (log_2 (x) \) times becomes \ (0 \ or \ 1 \) .
But there will be intervals addition, it can not do this stuff.
So we noticed a property:
in case:
\[x-\lfloor\frac{x}{d}\rfloor=z-\lfloor\frac{z}{d}\rfloor\]
Then there is for all \ (Y \) , if the \ (X \ Y leqslant \ leqslant Z \) , then:
\[x-\lfloor\frac{x}{d}\rfloor=y-\lfloor\frac{y}{d}\rfloor=z-\lfloor\frac{z}{d}\rfloor\]
prove:
If \ (X \ Y leqslant \ leqslant Z \) , then
\[\lfloor\frac{x}{d}\rfloor \leqslant \lfloor\frac{y}{d}\rfloor \leqslant \lfloor\frac{z}{d}\rfloor\]且\[\lfloor\frac{y}{d}\rfloor-\lfloor\frac{x}{d}\rfloor \leqslant y-x\]
EvidentShift key down:
\[x-\lfloor\frac{x}{d}\rfloor \leqslant y-\lfloor\frac{y}{d}\rfloor\]
Similarly available:
\[y-\lfloor\frac{y}{d}\rfloor \leqslant z-\lfloor\frac{z}{d}\rfloor\]
Therefore:
\[x-\lfloor\frac{x}{d}\rfloor \leqslant y-\lfloor\frac{y}{d}\rfloor \leqslant z-\lfloor\frac{z}{d}\rfloor\]
So when
\[x-\lfloor\frac{x}{d}\rfloor=z-\lfloor\frac{z}{d}\rfloor\]
When, for all \ (X \ Y leqslant \ leqslant Z \) , are met:
\[x-\lfloor\frac{x}{d}\rfloor = y-\lfloor\frac{y}{d}\rfloor =z-\lfloor\frac{z}{d}\rfloor\]
Proved.
Feel so a large section of the word say a bunch of nonsense ......
So every time we just determine what if this interval \ ([l, r] \ ) of:
\[minn-\lfloor\frac{minn}{d}\rfloor=maxn-\lfloor\frac{maxn}{d}\rfloor\]
Since there must be \ (minn \ leqslant a_l, a_ {l + 1}, ..., a_r \ leqslant maxn \)
So there must be
\[a_l-\lfloor\frac{a_l}{d}\rfloor=a_{l+1}-\lfloor\frac{a_{l+1}}{d}\rfloor=...=a_r-\lfloor\frac{a_r}{d}\rfloor\]
For every number \ (a_i \) , \ (a_i- \ lfloor \ FRAC} {D} {a_i \ rfloor \) is the \ (a_i \) becomes \ (\ lfloor \ frac {a_i } {d} \ rfloor \) need to reduce the number, so long as the \ (a_i \) subtracting \ (a_i- \ lfloor \ FRAC} {D} {a_i \ rfloor \) , the division can be achieved.
So that's a range of subtraction, because each number must subtract this value.
So this section of code:
void update2(int k,int l,int r,int ql,int qr,ll val)
{
int x=floor(1.0*minn[k]/val)-minn[k];
int y=floor(1.0*maxn[k]/val)-maxn[k];
if(ql<=l&&r<=qr&&x==y)
{
sum[k]+=x*(r-l+1);//区间加(减)
minn[k]+=x;
maxn[k]+=x;
lazy[k]+=x;
return;
}
int mid=(l+r)>>1;
down(k,l,r,mid);
if(ql<=mid)update2(k<<1,l,mid,ql,qr,val);
if(qr>mid)update2(k<<1|1,mid+1,r,ql,qr,val);
up(k);
}
Time complexity: \ (O (Q \ log (n-) \ log (V)) \) .
I will not permit ......
All code is as follows:
#include<bits/stdc++.h>
#define N 100010
#define ll long long
#define LNF 0x7fffffffffffffff
using namespace std;
int n,m,a[N];
ll sum[N<<2],minn[N<<2],maxn[N<<2],lazy[N<<2];
void downn(int k,int l,int r,ll val)
{
sum[k]+=val*(r-l+1);
minn[k]+=val;
maxn[k]+=val;
lazy[k]+=val;
}
void down(int k,int l,int r,int mid)
{
if(lazy[k])
{
downn(k<<1,l,mid,lazy[k]);
downn(k<<1|1,mid+1,r,lazy[k]);
lazy[k]=0;
}
}
void up(int k)
{
sum[k]=sum[k<<1]+sum[k<<1|1];
minn[k]=min(minn[k<<1],minn[k<<1|1]);
maxn[k]=max(maxn[k<<1],maxn[k<<1|1]);
}
void build(int k,int l,int r)
{
if(l==r)
{
scanf("%lld",&sum[k]);
maxn[k]=minn[k]=sum[k];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
up(k);
}
void update1(int k,int l,int r,int ql,int qr,ll val)
{
if(ql<=l&&r<=qr)
{
downn(k,l,r,val);
return;
}
int mid=(l+r)>>1;
down(k,l,r,mid);
if(ql<=mid)update1(k<<1,l,mid,ql,qr,val);
if(qr>mid)update1(k<<1|1,mid+1,r,ql,qr,val);
up(k);
}
void update2(int k,int l,int r,int ql,int qr,ll val)
{
if(ql<=l&&r<=qr&&floor(1.0*minn[k]/val)-minn[k]==floor(1.0*maxn[k]/val)-maxn[k])
{
ll tmp=floor(1.0*minn[k]/val)-minn[k];
downn(k,l,r,tmp);
return;
}
int mid=(l+r)>>1;
down(k,l,r,mid);
if(ql<=mid)update2(k<<1,l,mid,ql,qr,val);
if(qr>mid)update2(k<<1|1,mid+1,r,ql,qr,val);
up(k);
}
ll query1(int k,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
return minn[k];
int mid=(l+r)>>1;ll ans=LNF;
down(k,l,r,mid);
if(ql<=mid)ans=min(ans,query1(k<<1,l,mid,ql,qr));
if(qr>mid)ans=min(ans,query1(k<<1|1,mid+1,r,ql,qr));
return ans;
}
ll query2(int k,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
return sum[k];
int mid=(l+r)>>1;ll ans=0;
down(k,l,r,mid);
if(ql<=mid)ans+=query2(k<<1,l,mid,ql,qr);
if(qr>mid)ans+=query2(k<<1|1,mid+1,r,ql,qr);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--)
{
int opt,l,r;
scanf("%d%d%d",&opt,&l,&r);
l++,r++;
if(opt==1)
{
ll val;
scanf("%lld",&val);
update1(1,1,n,l,r,val);
}
if(opt==2)
{
ll val;
scanf("%lld",&val);
update2(1,1,n,l,r,val);
}
if(opt==3)
printf("%lld\n",query1(1,1,n,l,r));
if(opt==4)
printf("%lld\n",query2(1,1,n,l,r));
}
return 0;
}