题意
要求支持三种操作 1.区间求和 2.单点修改 3.区间取模
分析
问题主要在于区间取模
需要多维护一个区间最大值,当最大值已经小于模数的时候就不需要操作了
【先开始读错题了,写了个区间修改哎我没救了】
#include<bits/stdc++.h> using namespace std; #define N 110000 #define ll long long #define lc (p<<1) #define rc (p<<1|1) #define mid (t[p].l+t[p].r>>1) #define ll long long ll n,m,op; ll a[N]; struct email { ll sum,l,r,maxx; }t[N*4]; inline void pushnow(ll p,ll v) { t[p].sum+=v; t[p].maxx+=v; } inline void pushup(ll p) { t[p].sum=t[lc].sum+t[rc].sum; t[p].maxx=max(t[lc].maxx,t[rc].maxx); } void build(ll p,ll l,ll r) { t[p].l=l;t[p].r=r; if(l==r) { t[p].sum=a[l]; t[p].maxx=a[l]; return ; } ll m=l+r>>1; build(lc,l,m);build(rc,m+1,r); pushup(p); } void update(ll p,ll ql,ll qr,ll v) { if(ql<=t[p].l&&qr>=t[p].r) { pushnow(p,v); return ; } if(ql<=mid) update(lc,ql,qr,v); if(qr>mid) update(rc,ql,qr,v); pushup(p); } ll query(ll p,ll ql,ll qr) { ll ans=0; if(ql<=t[p].l&&qr>=t[p].r) return t[p].sum; if(ql<=mid) ans+=query(lc,ql,qr); if(qr>mid) ans+=query(rc,ql,qr); pushup(p); return ans; } void getmod(ll p,ll ql,ll qr,ll mod) { if(t[p].maxx<mod) return; if(t[p].l==t[p].r) { t[p].maxx%=mod; t[p].sum%=mod; return ; } if(ql<=mid)getmod(lc,ql,qr,mod); if(qr>mid)getmod(rc,ql,qr,mod); pushup(p); } int main() { scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); while(m--) { scanf("%lld",&op); if(op==2) { ll x,v; scanf("%lld%lld",&x,&v); ll w=query(1,x,x); update(1,x,x,v-w); } if(op==1) { ll l,r; scanf("%lld%lld",&l,&r); printf("%lld ",query(1,l,r)); } if(op==3) { ll l,r,mod; scanf("%lld%lld%lld",&l,&r,&mod); getmod(1,l,r,mod); } } return 0; }