题目:http://poj.org/problem?id=3468 题意:有N个整数,有两个操作,一个是对给定的区间增加值,一个是查询给定区间的和#include <stdio.h> const int maxn=100000; struct SegmentTree { int l, r; long long sum, lazy; }st[maxn<<2]; long long z[maxn+10], ans, c; int n, q, a, b; char ch[3]; void BuildTree(int v, int left, int right) { st[v].l=left, st[v].r=right, st[v].lazy=0; if (left==right) { st[v].sum=z[left]; return; } int lc=v<<1; int rc=lc+1; int mid=(left+right)>>1; BuildTree(lc, left, mid); BuildTree(rc, mid+1, right); st[v].sum=st[lc].sum+st[rc].sum; } void Insert(int left, int right, int v, long long x) { if (st[v].l==left&&st[v].r==right) { st[v].lazy+=x; return; } int lc=v<<1; int rc=lc+1; int mid=(st[v].l+st[v].r)>>1; st[v].sum+=(x*(right-left+1)); if (left>mid) Insert(left, right, rc, x); else if (right<=mid) Insert(left, right, lc, x); else { Insert(left, mid, lc, x); Insert(mid+1, right, rc, x); } } long long Query(int left, int right, int v) { if (st[v].l==left&&st[v].r==right) { ans+=st[v].sum+st[v].lazy*(right-left+1); return ans; } int lc=v<<1; int rc=lc+1; int mid=(st[v].l+st[v].r)>>1; st[v].sum+=st[v].lazy*(st[v].r-st[v].l+1); st[lc].lazy+=st[v].lazy, st[rc].lazy+=st[v].lazy; st[v].lazy=0; if (left>mid) Query(left, right, rc); else if (right<=mid) Query(left, right, lc); else Query(left, mid, lc)+Query(mid+1, right, rc); } int main() { //freopen("in.txt", "r", stdin); while (scanf("%d %d", &n, &q)==2) { for (int i=1; i<=n; i++) scanf("%lld", &z[i]); BuildTree(1, 1, n); for (int i=0; i<q; i++) { scanf("%s", ch); if (ch[0]=='C') { scanf("%d %d %lld", &a, &b, &c); Insert(a, b, 1, c); } else { scanf("%d %d", &a, &b); ans=0; printf("%lld\n", Query(a, b, 1)); } } } return 0; }
PKU 3468 A Simple Problem with Integers
最新推荐文章于 2017-03-05 19:43:41 发布