A Simple Problem with Integers

Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 47174   Accepted: 13844
Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

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

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.
 
解法:
一个树状数组,需要区间更新,区间求和,本来树状数组是区间更新单点求值或单点更新区间求和的,这个它是根据一些公式实现的:
 首先,看更新操作update(s, t, d)把区间A[s]...A[t]都增加d,我们引入一个数组delta[i],表示

A[i]...A[n]的共同增量,n是数组的大小。那么update操作可以转化为:

1)令delta[s] = delta[s] + d,表示将A[s]...A[n]同时增加d,但这样A[t+1]...A[n]就多加了d,所以

2)再令delta[t+1] = delta[t+1] - d,表示将A[t+1]...A[n]同时减d

然后来看查询操作query(s, t),求A[s]...A[t]的区间和,转化为求前缀和,设sum[i] = A[1]+...+A[i],则

A[s]+...+A[t] = sum[t] - sum[s-1],

那么前缀和sum[x]又如何求呢?它由两部分组成,一是数组的原始和,二是该区间内的累计增量和, 把数组A的原始

值保存在数组org中,并且delta[i]对sum[x]的贡献值为delta[i]*(x+1-i),那么

sum[x] = org[1]+...+org[x] + delta[1]*x + delta[2]*(x-1) + delta[3]*(x-2)+...+delta[x]*1

= org[1]+...+org[x] + segma(delta[i]*(x+1-i))

= segma(org[i]) + (x+1)*segma(delta[i]) - segma(delta[i]*i),1 <= i <= x

=segma(org[i]-delta[i]*i)+(x+1)*delta[i], i<=1<=x   //by huicpc0207 修改  这里就可以转化为两个个数组

这其实就是三个数组org[i], delta[i]和delta[i]*i的前缀和,org[i]的前缀和保持不变,事先就可以求出来,delta[i]和

delta[i]*i的前缀和是不断变化的,可以用两个树状数组来维护。

 #include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
#define ll long long int
ll a[];//维护delta[]
ll a1[];//维护delta[]*i
ll b[];//本来的数组和
int n;
int lowbit(int x)
{
return x&(-x);
}
void update(ll *arry,int x,int d)
{
while(x<=n)
{
arry[x]+=d;
x+=lowbit(x);
}
}
ll fun(ll *arry,int x)
{
ll sum=;
while(x>)
{
sum+=arry[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
//freopen("int.txt","r",stdin);
int k;
int x,i,y,z;
scanf("%d%d",&n,&k);
memset(b,,sizeof(b));
memset(a,,sizeof(a));
memset(a1,,sizeof(a1));
for(i=;i<=n;i++)
{
scanf("%d",&x);
b[i]+=b[i-]+x;
}
char c;
for(i=;i<k;i++)
{
c=getchar();
c=getchar();
if(c=='C')
{
scanf("%d%d%d",&x,&y,&z);
update(a,x,z);
update(a,y+,-z);
update(a1,x,z*x);
update(a1,y+,-z*(y+));
}
else
{
scanf("%d%d",&x,&y);
ll sum=-b[x-]-x*fun(a,x-)+fun(a1,x-);
sum+=b[y]+(y+)*fun(a,y)-fun(a1,y);
printf("%I64d\n",sum);
}
}
}

poj3468树状数组的区间更新,区间求和的更多相关文章

  1. POJ3468——树状数组支持两个区间操作

    题目:http://poj.org/problem?id=3468 推断过程可自己查,得式子:fixsum(x) = (x+1) * ∑(i=1,x)fi - ∑(i=1,x)i*fi; 其中 f 是 ...

  2. nyoj 123 士兵杀敌(四) 树状数组【单点查询+区间修改】

    士兵杀敌(四) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5   描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战 ...

  3. 【ZOJ2112】【整体二分+树状数组】带修改区间第k大

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  4. HDU 1166 敌兵布阵 树状数组小结(更新)

    树状数组(Binary Indexed Tree(BIT), Fenwick Tree) 是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有 元素之和,但是每次只能修改一 ...

  5. POJ3468(树状数组区间维护)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 89818   ...

  6. Turing Tree HDU - 3333 (树状数组,离线求区间元素种类数)

    After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because ...

  7. HDU 4638 Group (2013多校4 1007 离线处理+树状数组)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  8. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  9. 牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?

    开心.jpg J.farm 先解释一下题意,题意就是一个n*m的矩形区域,每个点代表一个植物,然后不同的植物对应不同的适合的肥料k,如果植物被撒上不适合的肥料就会死掉.然后题目将每个点适合的肥料种类( ...

随机推荐

  1. github如何添加ssh

    1.运行git Bash 输入如下命令: $ cd ~/.ssh $ ls 输入这2个命令 ,我们可以看到 id_rsa.pub 或 id_dsa.pub 这2个文件已经存在了,id_rsa 是私钥, ...

  2. Java 得到磁盘以及内存信息

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt217 1.得到磁盘信息 File[] files = File. listR ...

  3. [ASP.NET MVC]笔记(三) 成员资格、授权和安全性

    阻止CSRF(跨站请求伪造) ASP.NET MVC提供了一个阻止CSRF攻击的好方法 在每个提交的表单中包含 @using (Html.BeginForm("Index", &q ...

  4. 通过编译lambda表达式来创建实例(可在反射时候用,效率比反射高一些)

    原文地址:https://rogerjohansson.blog/2008/02/28/linq-expressions-creating-objects/ 据说编译lambda创建实例是比反射快.实 ...

  5. NHibernate教程(11)--多对多关联查询

    本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...

  6. 标题:a++和++a的区别

    以前我也是老搞不懂a++和++a的区别, 后来看了很多资料, 终于总结出来一条规律, 小白专用! 看完这个例子就懂了: 例1:$a = 8, 求 ++a + a++ - --a + a-- + ++a ...

  7. 英语学习案例分析APP 201421123108 王坤彬

    第一部分.调研,测评 1.第一次使用经验. 我使用的时候苹果手机下载的必应软件.第一次使用感觉还好,但是知名度比较低,比不上喜马拉雅听书软件,这里我就做两者的对比.首先界面以及种类明显逼格更差点.必应 ...

  8. 团队作业8——第二次项目冲刺(Beta阶段)第三天

    BETA阶段冲刺第三天 1.当天站立式会议 2.每个人的工作 (1)昨天已完成的工作: 编写页面讨论 (2)今天计划完成的工作: 完成编写页面 (3)工作中遇到的困难: 验证码正确度 (4)每个人的贡 ...

  9. 201521123048 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 //child public class test extends P ...

  10. 201521123070 《JAVA程序设计》第5周学习总结

    1. 本章学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. http://naotu.baidu.com/file/02b01f465e125c5942648a03358273b0 2. ...