POJ 3468 线段树模版

    xiaoxiao2023-11-14  145

    #include <iostream> #include <algorithm> using namespace std; #define ll long long const int maxn = 100005; int a[maxn]; struct N{ int l,r; ll pre,add; }node[4*maxn+5]; void build(int p,int l,int r){//区间编号p node[p].l = l; node[p].r = r; if(l==r){//叶子结点直接赋值 node[p].pre = a[l]; return ; } int mid = l+r >>1; build(2*p,l,mid); build(2*p+1,mid+1,r); node[p].pre = node[p*2].pre + node[p*2+1].pre;//维护区间和 } void spread(int p){ if(node[p].add){//如果标记不为0 向下传递 node[2*p].pre+=(node[2*p].r - node[2*p].l + 1)*node[p].add; node[2*p+1].pre+=(node[2*p+1].r - node[2*p+1].l + 1)*node[p].add; node[2*p].add+= node[p].add; node[2*p+1].add+= node[p].add; node[p].add = 0; } } void change(int p,int l,int r,int v){ if(node[p].l>=l&&node[p].r<=r){//区间被覆盖 就对其进行修改 node[p].pre+=(ll)v*(node[p].r-node[p].l+1); node[p].add+= v; //加上懒惰标记 return ; } spread(p);//没有覆盖 下放懒惰标记 考虑儿子区间可能因为懒惰标记存在而没有修改 int mid = node[p].l + node[p].r>>1; if(l<=mid)change(p*2,l,r,v); if(r>mid)change(p*2+1,l,r,v); node[p].pre = node[2*p].pre + node[2*p+1].pre; } ll query(int p,int l,int r){ if(l<=node[p].l&&r>=node[p].r){//被覆盖 返回值 return node[p].pre; } spread(p); ll ans = 0; int mid = node[p].r+node[p].l>>1; if(l<=mid)ans+=query(p*2,l,r); if(r>mid)ans+=query(p*2+1,l,r); return ans; } int main() { int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n); while(m--){ int l,r,k; char op; cin>>op>>l>>r; if(op=='C'){ scanf("%d",&k); change(1,l,r,k); }else { printf("%lld\n",query(1,l,r)); } } return 0; }

     

    最新回复(0)