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. Python常用库大全

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...

  2. Tensorflow 线性回归预测房价实例

    在本节中将通过一个预测房屋价格的实例来讲解利用线性回归预测房屋价格,以及在tensorflow中如何实现 Tensorflow 线性回归预测房价实例 1.1. 准备工作 1.2. 归一化数据 1.3. ...

  3. ASP.NET Core 运行原理解剖[5]:Authentication

    在现代应用程序中,认证已不再是简单的将用户凭证保存在浏览器中,而要适应多种场景,如App,WebAPI,第三方登录等等.在 ASP.NET 4.x 时代的Windows认证和Forms认证已无法满足现 ...

  4. MySQL索引选择及规则整理

    索引选择性就是结果个数与总个数的比值. 用sql语句表示为: SELECT COUNT(*) FROM table_name WHERE column_name/SELECT COUNT(*) FRO ...

  5. 阿里云centos下安装nginx、jdk、tomcat、绑定域名、解析域名

    1.ESC后安全设置(管理控制台->本实例安全组->配置规则->添加安全组规则->3306.80端口配置) 2.nginx  安装,首先安装三大件  PCRE.zlib.ope ...

  6. C# 反向生成工具(DAL BLL Modle)

    VS2015  ADO.NET无果后果断~! 动软生成:http://pan.baidu.com/s/1gfIf0ZL

  7. Java 关于路径

    在eclipse中如果没有指名文件的路径的话,系统默认是与src同一级别的目录路径!

  8. python re group()

    python group() 正则表达式中,group()用来提出分组截获的字符串,()用来分组 import re a = "123abc456" print re.search ...

  9. 【Alpha】——Second Scrum Meeting

    一.今日站立式会议照片 二.每个人的工作 成员 昨天已完成的工作 今天计划完成的工作 李永豪 完成登录按钮代码 完成添加功能 郑靖涛 完成登录按钮代码 完成删除功能 杨海亮 完成注册按钮代码 完成查找 ...

  10. 201521123105 第11周Java学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...