poj3468树状数组的区间更新,区间求和
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
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树状数组的区间更新,区间求和的更多相关文章
- POJ3468——树状数组支持两个区间操作
题目:http://poj.org/problem?id=3468 推断过程可自己查,得式子:fixsum(x) = (x+1) * ∑(i=1,x)fi - ∑(i=1,x)i*fi; 其中 f 是 ...
- nyoj 123 士兵杀敌(四) 树状数组【单点查询+区间修改】
士兵杀敌(四) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战 ...
- 【ZOJ2112】【整体二分+树状数组】带修改区间第k大
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- HDU 1166 敌兵布阵 树状数组小结(更新)
树状数组(Binary Indexed Tree(BIT), Fenwick Tree) 是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有 元素之和,但是每次只能修改一 ...
- POJ3468(树状数组区间维护)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 89818 ...
- Turing Tree HDU - 3333 (树状数组,离线求区间元素种类数)
After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because ...
- HDU 4638 Group (2013多校4 1007 离线处理+树状数组)
Group Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...
- 牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?
开心.jpg J.farm 先解释一下题意,题意就是一个n*m的矩形区域,每个点代表一个植物,然后不同的植物对应不同的适合的肥料k,如果植物被撒上不适合的肥料就会死掉.然后题目将每个点适合的肥料种类( ...
随机推荐
- DB Error || Warning
数据库在进行增删改查时有时候会发生错误,当在程序中一个操作总是不起作用的时候,我们可以尝试如下方法: 1.输出sql语句,有的sql语句可能是通过一些字符拼接完成的,这时候可能会发生'', +之类的混 ...
- ThinkPHP自定义分页模板
TpPageHelper.php <?php namespace tool; use think\Paginator; class TpPageHelper extends Paginator ...
- 常用bash命令
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545 } p. ...
- 极化码的matlab仿真(2)——编码
第二篇我们来介绍一下极化码的编码. 首先为了方便进行编码,我们需要进行数组的定义 signal = randi([0,1],1,ST); %信息位比特,随机二进制数 frozen = zeros(1, ...
- java设计模式系列之设计模式概要(1)
一.什么是设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...
- JQuery的动态加载class无法实现点击时间的解决方案
//对于 加载过来class 的del_a 实现点击事情 $(document).on('click',".del_a",function(){ $(".mark_id& ...
- servlet 返回json 数据
后端的数据需要返回简单的json数据: 发现通过双引号和单引号:" { 'name':123 } "的方式返回失败. 需要通过\转义里边的双引号: response.getWr ...
- 201521123020 《Java程序设计》第7周学习总结
1. 本周学习总结 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 public boolean contains(Object o) { re ...
- 201521123028《Java程序设计》第4周学习总结
1. 本周学习总结 2. 书面作业 Q1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看. 对上周PTA的实验5-3中的矩形和圆形类做注释. Q2.面向对象 ...
- 201521123088《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...