POJ 3468 A Simple Problem with Integers(线段树区间修改)

来源:互联网 发布:曾梵志 知乎 编辑:程序博客网 时间:2024/05/19 14:15

题目链接:http://poj.org/problem?id=3468

Description

给出了一个序列,你需要处理如下两种询问。

"C a b c"表示给[a, b]区间中的值全部增加c (-10000 c  10000)

"Q a b" 询问[a, b]区间中所有值的和。

Input

第一行包含两个整数N,Q。1 N,Q  100000.

第二行包含n个整数,表示初始的序列A (-1000000000 Ai 1000000000)。

接下来Q行询问,格式如题目描述。

Output

对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915


区间修改的第二道题,懒惰标记是add  要+= 不要=

注意区间的值会超Int

【源代码】

#include <iostream>#include <cstring>#include <cstdio>#define L(m) m<<1#define R(m) m<<1|1using namespace std;const int maxn  =100000+10;typedef long long ll;ll num[maxn];struct node{ll l,r,sum;ll add;}tree[maxn<<2];void pushup(ll m){tree[m].sum = tree[L(m)].sum + tree[R(m)].sum;}void pushdown(ll m){if(tree[m].add){ll tmp = tree[m].add;tree[L(m)].sum += (tree[L(m)].r-tree[L(m)].l+1)*tmp;tree[R(m)].sum += (tree[R(m)].r-tree[R(m)].l+1)*tmp;tree[L(m)].add +=tmp; //所有的都是 += ;tree[R(m)].add +=tmp;tree[m].add = 0;}}void Update(ll m,ll l,ll r,ll x){if(tree[m].l >=l && tree[m].r <=r){tree[m].add += x; //注意这里是+= 不是 =tree[m].sum += (tree[m].r - tree[m].l + 1) *x;return ;}pushdown(m);ll mid = (tree[m].l + tree[m].r)>>1;  //这里取中间取得是当前节点左右区间的中点if(mid>=r) 如果要更新的区间在左边 Update(L(m),l,r,x);else if(mid<l)Update(R(m),l,r,x);else{ Update(L(m),l,mid,x);Update(R(m),mid+1,r,x);}pushup(m);}ll Query(ll m,ll l,ll r){if(tree[m].l==l && tree[m].r==r){return tree[m].sum;}pushdown(m);ll mid = (tree[m].l+ tree[m].r)>>1;if(mid>=r)return Query(L(m),l,r);if(mid<l)return Query(R(m),l,r); //这里也可以写成 if else else ifreturn Query(L(m),l,mid)+Query(R(m),mid+1,r);}void Build(ll m,ll l,ll r){tree[m].l = l,tree[m].r = r;tree[m].add=0;  //不要忘了初始化if(l == r){tree[m].add = 0;tree[m].sum = num[l];return ;}int mid = (l + r)>>1;Build(L(m),l,mid);Build(R(m),mid+1,r);pushup(m);}int main(){ll n,q;while(scanf("%lld%lld",&n,&q)!=EOF){for(int i=1;i<=n;i++)scanf("%lld",&num[i]);// memset(tree,0,sizeof(tree));Build(1,1,n);char ch;ll a,b;ll c;while(q--){scanf(" %c",&ch);if(ch=='Q'){scanf("%lld%lld",&a,&b);printf("%lld\n",Query(1,a,b));}else{scanf("%lld%lld%lld",&a,&b,&c);Update(1,a,b,c);}}}return 0;}


0 0
原创粉丝点击