LOJ#6029「雅礼集训 2017 Day1」市场
https://loj.ac/p/6029
知识点:1.区间除法 (极限 ,势能分析)
2.除法 -> 减法 (类似有乘法 -> 加法 ,除法 -> 减法, 求幂->乘法)
3.极限 最多可能操作次数
#include <bits/stdc++.h> #define int long long using namespace std; int n,m; int a[100010]; int tre[400010],lazy[400010],maxn[400010],minn[400010]; int cal (int num,int k) { if(num >= 0) { return num - (num / k); } else if(num < 0) { int h = -num; int cha = h - ((h + k - 1) / k); return -cha; } } void down(int t,int l,int r,int k) { tre[t] += (r - l + 1) * k; lazy[t] += k; maxn[t] += k; minn[t] += k; return ; } void up(int t,int l,int r) { int mid = (l + r) >> 1; down(t << 1,l,mid,lazy[t]); down((t << 1) + 1,mid + 1,r,lazy[t]); lazy[t] = 0; return; } void built(int t,int l,int r) { if(l == r) { maxn[t] = a[l]; minn[t] = a[l]; tre[t] = a[l]; lazy[t] = 0; return ; } int mid = (l + r) >> 1; built(t << 1,l,mid); built((t << 1) + 1,mid + 1,r); tre[t] = tre[t << 1] + tre[(t << 1) + 1]; maxn[t] = max(maxn[t << 1],maxn[(t << 1) + 1]); minn[t] = min(minn[t << 1],minn[(t << 1) + 1]); return ; } void updatajia(int t,int l,int r,int L,int R,int k) { if(L <= l && r <= R) { tre[t] += (r - l + 1) * k; lazy[t] += k; maxn[t] += k; minn[t] += k; return; } int mid = (l + r) >> 1; up(t,l,r); if(L <= mid)updatajia(t << 1,l,mid, L,R,k); if(mid < R)updatajia((t << 1) + 1,mid + 1,r,L,R,k); tre[t] = tre[t << 1] + tre[(t << 1) + 1]; maxn[t] = max(maxn[t << 1],maxn[(t << 1) + 1]); minn[t] = min(minn[t << 1],minn[(t << 1) + 1]); return; } int query(int t,int l,int r,int L,int R) { if(L <= l && r <= R) { return tre[t]; } int mid = (l + r) >> 1; up(t,l,r); int ret = 0; if(L <= mid)ret += query(t << 1,l,mid,L,R); if(mid < R)ret += query((t << 1) + 1,mid + 1,r,L,R); return ret; } int querymin(int t,int l,int r,int L,int R) { if(L <= l && r <= R) { return minn[t]; } int mid = (l + r) >> 1; up(t,l,r); int ret = 999999999; if(L <= mid)ret = min(ret,querymin(t << 1,l,mid,L,R)); if(mid < R)ret = min(ret,querymin((t << 1) + 1,mid + 1,r,L,R)); return ret; } void updatachu(int t,int l,int r,int L,int R,int k) { if(L <= l && r <= R) { int maxcha = cal(maxn[t],k); int mincha = cal(minn[t],k); if(maxcha == mincha) { int kk = maxcha; tre[t] += (r - l + 1) * (-kk); lazy[t] += (-kk); maxn[t] += (-kk); minn[t] += (-kk); return; } } int mid = (l + r) >> 1; up(t,l,r); if(L <= mid)updatachu(t << 1,l,mid,L,R,k); if(mid < R)updatachu((t << 1) + 1,mid + 1,r,L,R,k); tre[t] = tre[t << 1] + tre[(t << 1) + 1]; maxn[t] = max(maxn[t << 1],maxn[(t << 1) + 1]); minn[t] = min(minn[t << 1],minn[(t << 1) + 1]); //lazy not ; return ; } signed main() { scanf("%lld%lld",&n,&m); for(int i = 1;i <= n;i++) { scanf("%lld",&a[i]); } int x,y,j,z; built(1,1,n); while(m--) { scanf("%lld%lld%lld",&x,&y,&j); if(x == 1) { scanf("%lld",&z); updatajia(1,1,n,y + 1,j + 1,z); } else if(x == 2) { scanf("%lld",&z); updatachu(1,1,n,y + 1,j + 1,z); } else if(x == 3) { printf("%lld\n",querymin(1,1,n,y + 1,j + 1)); } else if(x == 4) { printf("%lld\n",query(1,1,n,y + 1,j + 1)); } } return 0; }