原题链接:http://poj.org/problem?id=3468 题意:给定长度为n的数列A,执行两种操作:1.把l~r个数都加d;2.询问数列中l~r个数的和。 代码: #include iostream #include algorithm #include cstdio using namesp
原题链接: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)