洛谷 P3372 【模板】線段樹 1
阿新 • • 發佈:2020-12-07
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; int n,m; int a[N]; int l,r,x; struct Node{ int l,r; ll sum,add; }tr[N<<2]; void push_up(int u){ tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum; } void push_down(int u){ auto &root=tr[u],&left=tr[u<<1],&right=tr[u<<1|1]; if(root.add){ left.add+=root.add,left.sum+=(ll)(left.r-left.l+1)*root.add; right.add+=root.add,right.sum+=(ll)(right.r-right.l+1)*root.add; root.add=0; } } void build(int u,int l,int r){ if(l==r) tr[u]={l,r,a[r],0}; else{ tr[u]={l,r,0,0}; int mid=(l+r)>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); push_up(u); } } void modify(int u,int l,int r,int d){ if(tr[u].l>=l && tr[u].r<=r){ tr[u].sum+=(ll)(tr[u].r-tr[u].l+1)*d; tr[u].add+=d; } else{ push_down(u); int mid=(tr[u].l+tr[u].r)>>1; if(l<=mid) modify(u<<1,l,r,d); if(r>mid) modify(u<<1|1,l,r,d); push_up(u); } } ll query(int u,int l,int r){ if(tr[u].l>=l && tr[u].r<=r) return tr[u].sum; push_down(u); int mid=(tr[u].l+tr[u].r)>>1; ll sum=0; if(l<=mid) sum=query(u<<1,l,r); if(r>mid) sum+=query(u<<1|1,l,r); return sum; } int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n>>m; rep(i,1,n) cin>>a[i]; build(1,1,n); while(m--){ int op; cin>>op; if(op==1){ cin>>l>>r>>x; modify(1,l,r,x); } else{ cin>>l>>r; cout<<query(1,l,r)<<'\n'; } } return 0; } ```cpp