poj_3468: A Simple Problem with Integers (树状数组区间更新)
题目链接: http://poj.org/problem?id=3468
题目是对一个数组,支持两种操作
操作C:对下标从a到b的每个元素,值增加c;
操作Q:对求下标从a到b的元素值之和。
这道题也可以用线段树解,本文不做描述,下面分析如何用树状数组来解决这道题。
/*先把问题简化一点,因为 结果=初值+增量,所以,我们可以只对增量进行分析。然后,这种题有一个特点,就是如果对一般的一个操作C与操作查询前缀和的组合符合条件,那么无论进行多少次任意操作结果都是正确的。故 假设,先进行一次参数分别为 l,r,c 的操作C,再进行一次查询前缀和Si的操作(i 与l r的大小关系不定)。操作C之后,对Si,①当i<l时,Si=0,②当l<=i<r时,Si=c*(i-l+1),③当i>=r时,Si=c*(r-l+1)。要使情况①③满足比较简单,只需使add操作不在l左边进行,且对一树状数组的l和r分别进行+x+c*(r-l+1),-x的操作;而分析如何满足情况②,可以把Si看作是分布在直线y=c(x-l)=cx-cl上的一系列散点,易看出实现+cx的方法,就是在l执行add c的操作,在r执行add -c的操作,查询时查询sum()*x,而实现-cl的方法可以与上面“分别进行+x+c*(r-l+1),-x的操作”(引号中的x是不确定的)联系起来得出。故而任意Si都可以得出。*/
#include <cstdio> typedef long long LL; const int maxn =1e5+;
LL a[][maxn];
LL psum[maxn];
int n; inline int lowbit(int x)
{
return x&-x;
}
void add(LL a[],int x,int d)
{
while(x<=n)
{
a[x]+=d;
x+=lowbit(x);
}
}
LL sum(LL a[],int x)
{
LL ret=;
while(x)
{
ret+=a[x];
x-=lowbit(x);
}
return ret;
} LL query(int x)
{
return sum(a[],x)*x+sum(a[],x);
} int main()
{
int q;
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
scanf("%I64d",&psum[i]);
psum[i]+=psum[i-];
}
char op[];
while(q--)
{
int l,r;
scanf("%s%d%d",op,&l,&r);
if(op[]=='Q')
printf("%I64d\n",query(r)-query(l-)+psum[r]-psum[l-]);
else
{
int c;
scanf("%d",&c);
add(a[],l,c);
add(a[],r,-c);
add(a[],l,c*(-l+));
add(a[],r,c*r);
}
}
}
//上面内容废弃,以下解析为2018.05.30更新
假设数组用a[]表示,定义辅助数组s[]、d[],其具体含义为

且s[]、d[]间有如下关系

原题中对a[]的区间修改,可以视为对d[]的单点修改,而s[]又可以由d[i]、i*d[i]的前缀和推导出来。且维护s1[]、s2[]较容易,因为每次操作都是对d[]进行单点修改。具体可以参考以下代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
typedef long long LL; const int N=1e5+; LL s1[N],s2[N];
int n,q; inline int lowbit(int x)
{
return x&-x;
}
void add(LL a[],int i,LL x)
{
while(i<=n)
{
a[i]+=x;
i+=lowbit(i);
}
}
LL sum(LL a[],int i)
{
LL ret=;
while(i)
{
ret+=a[i];
i-=lowbit(i);
}
return ret;
}
void Add(int i,LL x)
{
add(s1,i,x*i),add(s2,i,x);
}
LL Sum(int i)
{
return -sum(s1,i)+(i+)*sum(s2,i);
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
LL t;
scanf("%lld",&t);
Add(i,t),Add(i+,-t);
}
while(q--)
{
int l,r;
char op[];
scanf("%s%d%d",op,&l,&r);
if(op[]=='Q')
printf("%lld\n",Sum(r)-Sum(l-));
else
{
LL t;
scanf("%lld",&t);
Add(l,t),Add(r+,-t);
}
}
}
poj_3468: A Simple Problem with Integers (树状数组区间更新)的更多相关文章
- POJ3468 A Simple Problem With Integers 树状数组 区间更新区间询问
今天学了很多关于树状数组的技巧.一个是利用树状数组可以简单的实现段更新,点询问(二维的段更新点询问也可以),每次修改只需要修改2个角或者4个角就可以了,另外一个技巧就是这题,原本用线段树做,现在可以用 ...
- HDU 4267 A Simple Problem with Integers --树状数组
题意:给一个序列,操作1:给区间[a,b]中(i-a)%k==0的位置 i 的值都加上val 操作2:查询 i 位置的值 解法:树状数组记录更新值. 由 (i-a)%k == 0 得知 i%k == ...
- A Simple Problem with Integers(树状数组HDU4267)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- 【poj2155】Matrix(二维树状数组区间更新+单点查询)
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
- 牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?
开心.jpg J.farm 先解释一下题意,题意就是一个n*m的矩形区域,每个点代表一个植物,然后不同的植物对应不同的适合的肥料k,如果植物被撒上不适合的肥料就会死掉.然后题目将每个点适合的肥料种类( ...
- POJ 3468 A Simple Problem with Integers(树状数组区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 97217 ...
- HDU 4267 A Simple Problem with Integers(树状数组区间更新)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- poj 3468: A Simple Problem with Integers (树状数组区间更新)
题目链接: http://poj.org/problem?id=3468 题目是对一个数组,支持两种操作 操作C:对下标从a到b的每个元素,值增加c: 操作Q:对求下标从a到b的元素值之和. 这道题也 ...
- POJ 3468 A Simple Problem with Integers(树状数组区间更新) 续
这个题刚开始的时候是套模板的,并没有真的理解什么树状数组的区间更新,这几天想了一下,下面是总结: 区间更新这里引进了一个数组delta数组,delta[i]表示区间 [i, n] 的共同增量,每次你需 ...
随机推荐
- Java IO流之随机读写流RandomAccessFile
随机读写流RandomAccessFile 简介 此类的实例支持对随机访问文件的**读取和写入**. 随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组. 存在指向该隐含数组的光标或索引 ...
- Python爬虫Dota排行榜爬取
1.分析网站 打开开发者工具,我们观察到排行榜的数据并没有在doc里 doc文档 在Javascript里我么可以看到下面代码: ajax的post方法异步请求数据 在 XHR一栏里,我们找到所请求的 ...
- dedecms后台添加新变量和删除变量的方法
下面由做网站为大家来介绍dedecms后台添加新变量和删除变量的方法 添加新变量是做什么用的?答:可以在模板内调用的东东. 一.进入网站织梦(Dedecms)后台(以dede5.5为例),依次打开系统 ...
- HTML/XML/XPATH基础
Html超文本标记语言 网页上单击右键→查看源文件/查看源代码 Html基本结构 <html> 为文档根元素,所有元素都在内部进行 <head> ...
- windows7 64bit下mvn命令后提示‘cmd’不是内部或外部命令,也不是可执行程序或批处理文件
首先,开命令提示符,输入如下命令试试echo %M2_HOME% 回车如果显示的路径和安装路径一致说明配置没问题; 那么出现这个问题的原因可能就是路径问题,可能是你安装了某个软件更改了系统映射路径导致 ...
- 导入网页数据到 Google Sheet
数据没有用,我们需要的是数据所反映出来的东西.增长率,排名,占比等.而这些结果是通过分析数据得到的. 从网上搜集到数据后,导入到表格程序中便可以进行方便地分析处理了.下面介绍将网页中的表格数据导入到 ...
- mac中使用 sourcetree 的快速配置和git服务器登录
问题: 1.mac中下载sourcetree配置仓库地址,一直在提示输入密码,无法登录成功,更无法获取源码. 2.找不到配置仓库时的账号密码,只看到地址. 场景: git服务器:自己的GIT服务器,非 ...
- ubuntu eclipse 建立server 提示coud not load the tomcat server configuration at /opt/apache ...的解决方法
ubuntu eclipse 建立server 提示coud not load the tomcat server configuration at /opt/apache ...的解决方法 & ...
- Access denied for user 'root'@'localhost' (using password: NO)错误的解决方案
在windows下使用PHP连接MYSQL数据库,确定MYSQL的服务已经启动了,而且Workbench也是可以连上去的,但是始终网页测试都提示Access Denied. 最终解决办法: set p ...
- Python Trick
一. 查询函数参数 import inspect print(inspect.getargspec(func)) 二. 查询对象属性 使用 dir() 查询对象属性 使用内置函数 hasattr(ob ...