P3372 【模板】线段树 1

it2022-05-05  142

https://www.luogu.org/problemnew/show/P3372

#include <iostream> #include <cstdio> #include <cmath> #define ll long long using namespace std; const int MAXN=400005; int n,m,x,u,v; ll k,jl[MAXN]; struct cyq{ int l,r; ll num,tip; }a[MAXN]; void build(int p,int l,int r){ a[p].l=l;a[p].r=r; if(l==r) {a[p].num=jl[l];return;} int mid=(l+r)>>1; build(p*2,l,mid);build(p*2+1,mid+1,r); a[p].num=a[p*2].num+a[p*2+1].num; } void spread(int p){ if(a[p].tip==0) return; a[p*2].num+=a[p].tip*(a[p*2].r-a[p*2].l+1); a[p*2+1].num+=a[p].tip*(a[p*2+1].r-a[p*2+1].l+1); a[p*2].tip+=a[p].tip;a[p*2+1].tip+=a[p].tip; a[p].tip=0; } void change(int p){ if(u<=a[p].l && v>=a[p].r){ a[p].num+=(ll)k*(a[p].r-a[p].l+1); a[p].tip+=k;return; }spread(p); int mid=(a[p].l+a[p].r)>>1; if(u<=mid) change(p*2); if(v>mid) change(p*2+1); a[p].num=a[p*2].num+a[p*2+1].num; } ll ask(int p) { if(u<=a[p].l && v>=a[p].r) return a[p].num; spread(p);long long ans=0; int mid=(a[p].l+a[p].r)>>1; if(u<=mid) ans+=ask(p*2); if(v>mid) ans+=ask(p*2+1); return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&jl[i]); build(1,1,n); for(int i=1;i<=m;i++){ scanf("%d",&x); if(x==1) { scanf("%d%d%lld",&u,&v,&k); change(1); } if(x==2) { scanf("%d%d",&u,&v); printf("%lld\n",ask(1)); } } return 0; }

最新回复(0)