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. 自己动手写java 字节流输入输出流

    数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流.   "流是磁盘或其它外围设备中存储的数据的源点或终点." ...

  2. base64随机字符混淆加密、解密-美拍视频地址解密,反推加密算法

    用火车头测试采集美拍的数据时无意中发现美拍的视频地址是一段加了混淆字符串的base64代码.如下图 于是好奇之下研究了下解密算法.具体过程省略800字.发现美拍的视频解密是通过js完成,于是找到了具体 ...

  3. Maven setting.xml 文件剖析

    全局配置: ${M2_HOME}/conf/settings.xml (配置环境变量  新建 M2_HOME    安装目录到版本名那里(D:\apache-maven-3.0.2) 编辑path 环 ...

  4. liunx下常见的命令汇总

    前言:这篇文章对于工作多年的可能用处不大,但对于刚刚接触Java的同学肯定是有一些帮助,现在我总结我接触liunx后常见的一些命令 1:日志查询常用的命令 ll:查询目录下所有的文件 ls -lht: ...

  5. vue引入百度地图api组件封装(根据地址定位)

    Map.vue <template> <div class="Map" :style="{ height: this.height+'px', widt ...

  6. vim插件ctags的安装与使用

    LINUX系统下看程序或者编程序时,看到一个函数经常需要知道该函数的定义,这时ctags就派上用场了,其安装和使用方法如下: 安装方法: sudo apt-get install ctags (ubu ...

  7. !Web云笔记--HTML基础

    Web自学笔记第一阶段笔记综合汇总 参考资料:<Head First HTML&CSS>(中文第二版)(美国)弗里昂ISBN:9787508356464 中国电力出版社 全部阶段: ...

  8. UX是什么?

    UX(用户体验),操作过安卓手机或者苹果手机的系统吧?那么操作过程的整体体验就叫UX,而操作过程中所看到的界面颜色啦,图案,字体大小啦等等都属于UI设计,而交互设计(Interaction Desig ...

  9. MySQL(四)--蠕虫复制、查询

    1 蠕虫复制 蠕虫复制:从已有的数据中去获取数据,然后将数据又进行新增操作,数据成倍增加. 表创建高级操作:从已有创建新表(复制表结构) create table 表名 like 数据库.表名; 蠕虫 ...

  10. 控制结构(9) 管道(pipeline)

    // 上一篇:线性化(linearization) // 下一篇:指令序列(opcode) 最近阅读了酷壳上的一篇深度好文:LINUX PID 1 和 SYSTEMD.这篇文章介绍了systemd干掉 ...