POJ 3468 A Simple Problem with Integers (树状数组写法)

来源:互联网 发布:如何评价罗马文明 知乎 编辑:程序博客网 时间:2024/05/17 08:05

题意: 给出一段序列,支持区间增减,区间查询。

解法: 数据结构成端更新的入门题了,这次又拿来试了试树状数组。

树状数组成段更新的教程

常数小果然飞起啊,splay 3907MS,线段树 1875MS,树状数组 969MS- -。

/* **********************************************Author      : NeroCreated Time: 2013-8-31 17:47:36Problem id  : POJ 3468Problem Name: A Simple Problem with Integers *********************************************** */#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define REP(i,a,b) for(int i=(a); i<(int)(b); i++)#define clr(a,b) memset(a,b,sizeof(a))typedef long long lld;const int MAXN = 101000;int n;lld c[MAXN];lld delta[MAXN];lld deltai[MAXN];void add(lld *t, int p, int d) {    for( ; p <= n; p += p&-p) t[p] += d;}lld sum(lld *t, int p) {    lld ret = 0;    for( ; p > 0; p -= p&-p) ret += t[p];    return ret;}lld query(int l, int r) {    lld ret = 0;    ret += c[r] + sum(delta, r) * (r+1) - sum(deltai, r);    ret -= c[l-1] + sum(delta, l-1) * l - sum(deltai, l-1);    return ret;}void update(int l, int r, int x) {    add(delta, l, x);    add(deltai, l, x * l);    add(delta, r+1, -x);    add(deltai, r+1, -x * (r+1));}int main() {    int nq,d;    while(~scanf("%d%d", &n, &nq)) {        clr(c,0);        clr(delta,0);        clr(deltai,0);        for(int i = 1; i <= n; i ++) {            scanf("%lld", &c[i]);            c[i] += c[i-1];        }        char s[10];        int a,b;        while(nq --) {            scanf("%s%d%d", s, &a, &b);            if(s[0] == 'Q') {                printf("%lld\n", query(a,b));            }            else {                int x;                scanf("%d", &x);                update(a,b,x);            }        }    }    return 0;}


原创粉丝点击