It's amazing to change division into subtraction After writing, I was confused. I couldn't find out a sb mistake
Problem description
input
In the first line, the integer n,q separated by two spaces represent the number of vendors and the number of orders + inquiries respectively.
The second line contains n integers a0 ∼ an − 1 separated by spaces
Next, q line, each line represents an operation, the first number represents operation number 1 ∼ 4, and the following input is consistent with the problem description.
output
For each 3, 4 operation, output the query answer.
sample input
10 10
-5 -4 -3 -2 -1 0 1 2 3 4
1 0 4 1
1 5 9 1
2 0 9 3
3 0 9
4 0 9
3 0 1
4 2 3
3 4 5
4 6 7
3 8 9
sample output
-2
-2
-2
-2
0
1
1
For 30% data, n,q ≤ 10 ^ 3;
For 60% of the data, ensure that the data is random;
For 100% data, 1 ≤ n,q ≤ 10 ^ 5,0 ≤ l ≤ r ≤ n − 1,c ∈ [- 10^4,10^4],d ∈ [2,10 ^ 9]
(PS: there is a small mistake in the title description, which should be seen.)
Title Solution
Maintain interval sum, maximum value and minimum value. If the difference between the maximum value after division and the minimum value after division is the same, the difference can be marked (that is, the mark from division to interval subtraction)
It's been a long time since I checked it out )
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define lc (o<<1)
#define rc (o<<1|1)
#define mid (l+r>>1)
int n,q;//Number of people, decree+Number of inquiries
typedef long long ll;
const int N=1e5+10;
ll a[N];
ll sum[N<<2];
ll mx[N<<2];
ll mn[N<<2];
ll lazy[N<<2];
inline ll divide(ll x,ll y)
{
return floor((double)x/y);
}
inline void push_up(int o)
{
sum[o]=sum[lc]+sum[rc];
mx[o]=max(mx[lc],mx[rc]);
mn[o]=min(mn[lc],mn[rc]);
}
void build(int o,int l,int r)
{
if(l==r)
{
mx[o]=mn[o]=sum[o]=a[l];
lazy[o]=0;
return;
}
build(lc,l,mid);build(rc,mid+1,r);
#ifdef debug
puts("-1");
#endif
push_up(o);
}
inline void push_down(int o,int l,int r)
{
if(!lazy[o])return;
lazy[lc]+=lazy[o];
sum[lc]+=(mid-l+1)*lazy[o];
mx[lc]+=lazy[o];
mn[lc]+=lazy[o];
lazy[rc]+=lazy[o];
sum[rc]+=(r-mid)*lazy[o];
mx[rc]+=lazy[o];
mn[rc]+=lazy[o];
lazy[o]=0;
#ifdef debug
puts("-2");
#endif
}
void add(int o,int l,int r,int nl,int nr,ll v)
{
if(l<r)push_down(o,l,r);
if(nl<=l&&r<=nr)
{
sum[o]+=(ll)(r-l+1)*v;
lazy[o]+=v;
mn[o]+=v;
mx[o]+=v;
return;
}
if(nl<=mid)add(lc,l,mid,nl,nr,v);
if(nr>mid)add(rc,mid+1,r,nl,nr,v);
#ifdef debug
puts("-3");
#endif
push_up(o);
}
void div(int o,int l,int r,int nl,int nr,ll v)
{
if(l<r)push_down(o,l,r);
if(nl<=l&&r<=nr)
{
ll m1=divide(mx[o],v);
ll m2=divide(mn[o],v);
if(mx[o]-m1==mn[o]-m2)
{
ll k=mx[o]-m1;
sum[o]-=k*(r-l+1);//It has been written. k*(r-l+1)*vSurprised
mx[o]-=k;
mn[o]-=k;
lazy[o]-=k;
return;
}
}
if(nl<=mid)div(lc,l,mid,nl,nr,v);
if(nr>mid)div(rc,mid+1,r,nl,nr,v);
push_up(o);
#ifdef debug
puts("-4");
#endif
}
ll query_min(int o,int l,int r,int nl,int nr)
{
#ifdef debug
puts("-5");
#endif
if(nl<=l&&r<=nr)
return mn[o];
push_down(o,l,r);
if(nr<=mid)return query_min(lc,l,mid,nl,nr);
else if(nl>mid)return query_min(rc,mid+1,r,nl,nr);
else return min(query_min(lc,l,mid,nl,mid),query_min(rc,mid+1,r,mid+1,nr));
}
ll query_sum(int o,int l,int r,int nl,int nr)
{
#ifdef debug
puts("-6");
#endif
if(nl<=l&&r<=nr)
return sum[o];
push_down(o,l,r);
if(nr<=mid)return query_sum(lc,l,mid,nl,nr);
else if(nl>mid)return query_sum(rc,mid+1,r,nl,nr);
else return query_sum(lc,l,mid,nl,mid)+query_sum(rc,mid+1,r,mid+1,nr);
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&q);
int op,x,y;
ll z;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(int i=1;i<=q;i++)
{
scanf("%d",&op);
if(op==1)
scanf("%d%d%lld",&x,&y,&z),add(1,1,n,x+1,y+1,z);
else if(op==2)
scanf("%d%d%lld",&x,&y,&z),div(1,1,n,x+1,y+1,z);
else if(op==3)
scanf("%d%d",&x,&y),printf("%lld\n",query_min(1,1,n,x+1,y+1));
else if(op==4)
scanf("%d%d",&x,&y),printf("%lld\n",query_sum(1,1,n,x+1,y+1));
}
return 0;
}