标签:
题目链接: http://poj.org/problem?id=3468
题意: 给出一个序列,然后会有两种操作,一是让下标从 i - j 都增加 某个固定值, 二是询问你下标从 m - n 这个区域的和是多少?
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <map> #include <stack> #include <cstring> using namespace std; typedef long long LL; #define INF 0xfffffff #define maxn 110000 #define lson rt<<1 #define rson rt<<1|1 int A[maxn]; struct node { int l, r; int len() { return r-l+1; } LL s, e; } tree[maxn<<2]; void build(int l, int r, int rt) { tree[rt].l = l; tree[rt].r = r; tree[rt].e = 0; if(l == r) { tree[rt].s = A[l]; return ; } int mid = (l+r)/2; build(l, mid, lson); build(mid+1, r, rson); tree[rt].s = tree[lson].s + tree[rson].s; } void down(int rt) { tree[lson].s += tree[lson].len()*tree[rt].e; tree[rson].s += tree[rson].len()*tree[rt].e; tree[lson].e += tree[rt].e; tree[rson].e += tree[rt].e; tree[rt].e = 0; } void update(int l, int r, int val, int rt) { tree[rt].s += val*(r-l+1); if(tree[rt].l == l && tree[rt].r == r) { tree[rt].e += val; return ; } down(rt); int mid = (tree[rt].l + tree[rt].r)/2; if(r<=mid) update(l, r, val, lson); else if(l>mid) update(l, r, val, rson); else { update(l, mid, val, lson); update(mid+1, r, val, rson); } } LL query(int l, int r, int rt) { if(tree[rt].l == l && r == tree[rt].r) return tree[rt].s; down(rt); int mid = (tree[rt].l + tree[rt].r)/2; if(r<=mid) return query(l, r, lson); else if(l>mid) return query(l, r, rson); else { LL lsum, rsum; lsum = query(l, mid, lson); rsum = query(mid+1, r, rson); return lsum+rsum; } } int main() { int n, m, a, b, c; char op; scanf("%d %d",&n, &m); for(int i=1; i<=n; i++) scanf("%d", &A[i]); build(1, n, 1); while(m --) { getchar(); scanf("%c %d %d", &op, &a, &b); if(op==‘Q‘) { LL ans = query(a, b, 1); printf("%I64d\n", ans); continue; } scanf("%d", &c); update(a, b, c, 1); } return 0; }
A Simple Problem with Integers POJ 3468
标签:
原文地址:http://www.cnblogs.com/daydayupacm/p/5679284.html