POJ 3468 [模板] 延迟标记(懒标记) 线段树
Posted neveah
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3468 [模板] 延迟标记(懒标记) 线段树相关的知识,希望对你有一定的参考价值。
原题链接:http://poj.org/problem?id=3468
题意:给定长度为n的数列A,执行两种操作:1.把l~r个数都加d;2.询问数列中l~r个数的和。
代码:
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; #define N 100010 typedef long long ll; struct node int l,r; ll sum,add; tree[4*N]; int a[N],n,m; void build(int p,int l,int r) tree[p].l=l;tree[p].r=r; if(l==r) tree[p].sum=a[l]; return ; int mid=(l+r)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); tree[p].sum=tree[p*2].sum+tree[p*2+1].sum; void spread(int p) if(tree[p].add) tree[p*2].sum+=tree[p].add*(tree[p*2].r-tree[p*2].l+1); tree[p*2+1].sum+=tree[p].add*(tree[p*2+1].r-tree[p*2+1].l+1); tree[p*2].add+=tree[p].add; tree[p*2+1].add+=tree[p].add; tree[p].add=0; void change(int p,int l,int r,int d) if(l<=tree[p].l&&r>=tree[p].r) tree[p].sum+=(long long)d*(tree[p].r-tree[p].l+1); tree[p].add+=d; return ; spread(p); int mid=(tree[p].l+tree[p].r)/2; if(l<=mid) change(p*2,l,r,d); if(r>mid) change(p*2+1,l,r,d); tree[p].sum=tree[p*2].sum+tree[p*2+1].sum; long long ask(int p,int l,int r) if(l<=tree[p].l&&r>=tree[p].r) return tree[p].sum; spread(p); int mid=(tree[p].l+tree[p].r)/2; long long val=0; if(l<=mid) val+=ask(p*2,l,r); if(r>mid) val+=ask(p*2+1,l,r); return val; int main(int argc, char** argv) scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); while(m--) char op[2]; int l,r,d; scanf("%s%d%d",op,&l,&r); if(op[0]==‘C‘) scanf("%d",&d); change(1,l,r,d); else printf("%lld\n",ask(1,l,r)); return 0;
(见[算法进阶指南]P217)
以上是关于POJ 3468 [模板] 延迟标记(懒标记) 线段树的主要内容,如果未能解决你的问题,请参考以下文章
POJ-3468 A Simple Problem with Integers
POJ 3468 A Simple Problem with Integers